]> xenbits.xensource.com Git - xcp/xen-api.git/commitdiff
CA-46050: allow more than 2 PCI devices to be hotplugged into a domain (!)
authorDavid Scott <dave.scott@eu.citrix.com>
Mon, 11 Oct 2010 22:00:16 +0000 (23:00 +0100)
committerDavid Scott <dave.scott@eu.citrix.com>
Mon, 11 Oct 2010 22:00:16 +0000 (23:00 +0100)
There is much confusion about the meaning of the X in
(X, (domain, bus, path, func)). Sometimes it means "order the device was
plugged"; other times it means something more device related.

With this change, more than 2 devices can be plugged into a domain and the
#devices and plug order remains constant over reboot.

Signed-off-by: David Scott <dave.scott@eu.citrix.com>
ocaml/xapi/vmops.ml
ocaml/xenops/device.ml
ocaml/xenops/device.mli
ocaml/xenops/xenops.ml

index bc066d0c98d19b8a5f021710720b7a4988de14c2..8ad15f9bac156c14058b752f044f560fe4887e4d 100644 (file)
@@ -506,12 +506,12 @@ let plug_pcidevs_noexn ~__context ~vm domid pcidevs =
           (fun xc xs ->
              if (Xc.domain_getinfo xc domid).Xc.hvm_guest then begin
                        List.iter 
-                               (fun (devid, devices) ->
+                               (fun (_, devices) ->
                                         Device.PCI.bind devices;
                                         List.iter
                                                 (fun ((a, b, c, d) as device) ->
                                                          debug "hotplugging PCI device %04x:%02x:%02x.%01x into domid: %d" a b c d domid;
-                                                         Device.PCI.plug ~xc ~xs device domid devid
+                                                         Device.PCI.plug ~xc ~xs device domid
                                                 ) devices
                                ) (sort_pcidevs pcidevs)
              end
index 3094a993eedbbd348270f1ddcac20a6acf387f84..92b476cf8a9a85a6740aed301cc41f1ca7479ddc 100644 (file)
@@ -1174,25 +1174,28 @@ let wait_device_model ~xc ~xs domid =
   xs.Xs.rm (device_model_state_path xs be_domid domid);
   answer
                                                        
-(* Return a list of PCI devices *)
-let list ~xc ~xs domid = 
+(* Given a domid, return a list of [ X, (domain, bus, dev, func) ] where X indicates the order in
+   which the device was plugged. *)
+let read_pcidir ~xc ~xs domid = 
   let path = device_model_pci_device_path xs 0 domid in
   let prefix = "dev-" in
   let all = List.filter (String.startswith prefix) (try xs.Xs.directory path with Xb.Noent -> []) in
   (* The values are the PCI device (domain, bus, dev, func) strings *)
-  let pairs = List.map (fun x -> x, xs.Xs.read (path ^ "/" ^ x)) all in
   let device_number_of_string x =
     (* remove the silly prefix *)
     int_of_string (String.sub x (String.length prefix) (String.length x - (String.length prefix))) in
-  let pairs' = List.map (fun (x, y) -> device_number_of_string x, of_string y) pairs in
+  let pairs = List.map (fun x -> device_number_of_string x, of_string (xs.Xs.read (path ^ "/" ^ x))) all in
   (* Sort into the order the devices were plugged *)
-  let sorted = List.sort (fun a b -> compare (fst a) (fst b)) pairs' in
-  (* Assume the PCI bus ID is 0 *)
-  List.map (fun (_, y) -> 0, y) sorted
+  List.sort (fun a b -> compare (fst a) (fst b)) pairs
+
+(* Return a list of PCI devices *)
+let list ~xc ~xs domid = 
+       (* replace the sort index with the default '0' -- XXX must figure out whether this matters to anyone *)
+       List.map (fun (_, y) -> (0, y)) (read_pcidir ~xc ~xs domid)
 
 
-let plug ~xc ~xs (domain, bus, dev, func) domid devid 
-    let current = list ~xc ~xs domid in
+let plug ~xc ~xs (domain, bus, dev, func) domid = 
+    let current = read_pcidir ~xc ~xs domid in
        let next_idx = List.fold_left max (-1) (List.map fst current) + 1 in
        
        let pci = to_string (domain, bus, dev, func) in
index 6dd153cddbd992c25aecdef24fc3817a4ffffacf..fa034ff304433514df1e381f094b6e2b359b81c9 100644 (file)
@@ -145,7 +145,7 @@ sig
        val reset : xs:Xs.xsh -> device -> unit
        val bind : (int * int * int * int) list -> unit
        val plug : xc:Xc.handle -> xs:Xs.xsh
-               -> (int * int * int * int) -> Xc.domid -> int -> unit
+               -> (int * int * int * int) -> Xc.domid -> unit
        val unplug : xc:Xc.handle -> xs:Xs.xsh
                -> (int * int * int * int) -> Xc.domid -> unit
        val list : xc:Xc.handle -> xs:Xs.xsh -> Xc.domid -> (int * (int * int * int * int)) list
index 08148fb19be7c981beb9cda92b1eb6b015c4af7e..5a13cc9724b582ff9a0b7b59c4f57dcc16efb49d 100644 (file)
@@ -258,7 +258,7 @@ let add_pci ~xc ~xs ~hvm ~domid ~devid ~pci =
 
 let plug_pci ~xc ~xs ~domid ~devid ~pci = 
        let pcidev = pci_of_string pci in
-       Device.PCI.plug ~xc ~xs pcidev domid devid
+       Device.PCI.plug ~xc ~xs pcidev domid
 
 let unplug_pci ~xc ~xs ~domid ~devid ~pci = 
        let pcidev = pci_of_string pci in