# HG changeset patch # User David Scott # Date 1270497002 -3600 # Node ID 9d41a85de51298757c474717f2f948e3c6121e00 # Parent 4ee206f7ec1f68139abd3bc8d24537f879c8bf04 CA-39889: hotplug PCI devices into guests in the order specified in the (original) other-config key. There were two problems: 1. xapi was accidentally reversing the list provided in the other_config key (a side-effect of a fold) 2. when listing the PCI devices present in xenstore, the Device.PCI.list function was passing the device order number back in the place reserved for "PCI bus ID". This caused the devices to be hotplugged in reverse over reboot. Now the behaviour is: 1. devices are hotplugged in the order they are found in the other_config key 2. the hotplug ordering is stable across start/internal reboot/external reboot Signed-off-by: David Scott diff -r 4ee206f7ec1f -r 9d41a85de512 ocaml/xapi/vmops.ml --- a/ocaml/xapi/vmops.ml Tue Mar 09 16:02:02 2010 +0000 +++ b/ocaml/xapi/vmops.ml Mon Apr 05 20:50:02 2010 +0100 @@ -489,6 +489,8 @@ (fun id a b c d -> (id, (a, b, c, d))) :: acc with _ -> acc ) [] devs in + (* Preserve the configured order *) + let devs = List.rev devs in if devs <> [] then Rbac.assert_permission ~__context ~permission:Rbac_static.permission_internal_vm_plug_pcidevs; devs diff -r 4ee206f7ec1f -r 9d41a85de512 ocaml/xapi/xapi_vm.ml --- a/ocaml/xapi/xapi_vm.ml Tue Mar 09 16:02:02 2010 +0000 +++ b/ocaml/xapi/xapi_vm.ml Mon Apr 05 20:50:02 2010 +0100 @@ -399,6 +399,7 @@ (* Before we destroy the old domain we check which PCI devices were plugged in *) let pcidevs = with_xc_and_xs (fun xc xs -> Device.PCI.list xc xs domid) in + debug "Listed PCI devices: [ %s ]" (String.concat ", " (List.map (fun (x, dev) -> string_of_int x ^ "/" ^ (Device.PCI.to_string dev)) pcidevs)); let localhost = Helpers.get_localhost ~__context in debug "%s phase 1/3: destroying old domain" api_call_name; diff -r 4ee206f7ec1f -r 9d41a85de512 ocaml/xenops/device.ml --- a/ocaml/xenops/device.ml Tue Mar 09 16:02:02 2010 +0000 +++ b/ocaml/xenops/device.ml Mon Apr 05 20:50:02 2010 +0100 @@ -1188,7 +1188,11 @@ 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 - List.map (fun (x, y) -> device_number_of_string x, of_string y) pairs + let pairs' = List.map (fun (x, y) -> device_number_of_string x, of_string y) pairs 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 let plug ~xc ~xs (domain, bus, dev, func) domid devid =