# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1263336663 0
# Node ID aacf1b563353749ebb9d6f0d8b89327de784bcdf
# Parent 7ec163e4ed6c8efd53e3996a2e58abaf0213aec5
CA-36384: [experimental PCI passthrough]: Make reboot + PCI passthrough use the
devices in Device.PCI.list rather than new values from the VM record. This
makes internal reboot keep the PCI device: previously the attempt to read the
new value would fail the RBAC permission check.
The only downside of this is that to change the PCI device, you have to
shutdown and restart.
Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>
diff -r 7ec163e4ed6c -r aacf1b563353 ocaml/xapi/vmops.ml
--- a/ocaml/xapi/vmops.ml Tue Jan 12 22:51:03 2010 +0000
+++ b/ocaml/xapi/vmops.ml Tue Jan 12 22:51:03 2010 +0000
@@ -115,13 +115,24 @@
raise (Api_errors.Server_error (Api_errors.cannot_plug_vif, [
Ref.string_of vif.Vm_config.vif_ref ]))
) vifs
+let sort_pcidevs devs =
+ let ids = ref [] in
+ List.iter (fun (id, _) ->
+ if not (List.mem id !ids) then
+ ids := id :: !ids
+ ) devs;
+
+ List.map (fun id ->
+ id, (List.map snd (List.filter (fun (x, _) ->
x = id) devs))
+ ) !ids
+
let attach_pcis ~__context ~xc ~xs ~hvm domid pcis =
Helpers.log_exn_continue "attach_pcis"
(fun () ->
List.iter (fun (devid, devs) ->
Device.PCI.bind devs;
Device.PCI.add ~xc ~xs ~hvm
~msitranslate:0 ~pci_power_mgmt:0 devs domid devid
- ) pcis
+ ) (sort_pcidevs pcis)
) ()
(* Called on both VM.start and VM.resume codepaths to create vcpus in xenstore
*)
@@ -478,18 +489,9 @@
(fun id a b c d -> (id, (a, b, c, d))) ::
acc
with _ -> acc
) [] devs in
- let ids = ref [] in
- List.iter (fun (id, _) ->
- if not (List.mem id !ids) then
- ids := id :: !ids
- ) devs;
- let pcidevs =
- List.map (fun id ->
- id, (List.map snd (List.filter (fun (x,
_) -> x = id) devs))
- ) !ids in
- if pcidevs <> []
+ if devs <> []
then Rbac.assert_permission ~__context
~permission:Rbac_static.permission_internal_vm_plug_pcidevs;
- pcidevs
+ devs
(* Hotplug the PCI devices into the domain (as opposed to 'attach_pcis') *)
let plug_pcidevs ~__context ~vm domid pcidevs =
@@ -508,7 +510,7 @@
debug "hotplugging
PCI device %04x:%02x:%02x.%01x into domid: %d" a b c d domid;
Device.PCI.plug ~xc
~xs device domid devid
) devices
- ) pcidevs
+ ) (sort_pcidevs pcidevs)
end
)
end;
@@ -916,7 +918,7 @@
(** Starts up a VM, leaving it in the paused state *)
-let start_paused ?(progress_cb = fun _ -> ()) ~__context ~vm ~snapshot =
+let start_paused ?(progress_cb = fun _ -> ()) ~pcidevs ~__context ~vm
~snapshot =
check_vm_parameters ~__context ~self:vm ~snapshot;
(* Take the subset of locked VBDs *)
let other_config = Db.VM.get_other_config ~__context ~self:vm in
@@ -970,6 +972,9 @@
if Xapi_globs.xenclient_enabled then
Domain.cpuid_apply ~xc ~hvm domid;
+ (* XXX: PCI passthrough needs a lot of work *)
+ let pcidevs = (match pcidevs with Some x -> x | None
-> pcidevs_of_vm ~__context ~vm) in
+
(* Don't attempt to attach empty VBDs to PV guests: they
can't handle them *)
let vbds =
if hvm then vbds
@@ -1002,9 +1007,8 @@
let vifs = Vm_config.vifs_of_vm ~__context ~vm
domid in
create_vifs ~__context ~xs vifs;
progress_cb 0.70;
- (* XXX: PCI passthrough needs a lot of work *)
if not hvm
- then attach_pcis ~__context ~xc ~xs ~hvm domid
(pcidevs_of_vm ~__context ~vm);
+ then attach_pcis ~__context ~xc ~xs ~hvm domid
pcidevs;
if (Xapi_globs.xenclient_enabled) && (not hvm) &&
(has_platform_flag snapshot.API.vM_platform "pv_qemu") then
@@ -1014,7 +1018,7 @@
progress_cb 0.80;
debug "creating device emulator";
let vncport = create_device_emulator ~__context
~xc ~xs ~self:vm domid vifs snapshot in
- if hvm then plug_pcidevs ~__context ~vm domid
(pcidevs_of_vm ~__context ~vm);
+ if hvm then plug_pcidevs ~__context ~vm domid
pcidevs;
create_console ~__context ~vM:vm ~vncport ();
debug "writing memory policy";
write_memory_policy ~xs snapshot domid;
diff -r 7ec163e4ed6c -r aacf1b563353 ocaml/xapi/xapi_vm.ml
--- a/ocaml/xapi/xapi_vm.ml Tue Jan 12 22:51:03 2010 +0000
+++ b/ocaml/xapi/xapi_vm.ml Tue Jan 12 22:51:03 2010 +0000
@@ -248,7 +248,7 @@
debug "start: bringing up domain in the paused state";
Vmops.start_paused
- ~progress_cb:(TaskHelper.set_progress ~__context) ~__context
~vm ~snapshot;
+ ~progress_cb:(TaskHelper.set_progress ~__context) ~pcidevs:None
~__context ~vm ~snapshot;
delete_guest_metrics ~__context ~self:vm;
let localhost = Helpers.get_localhost ~__context in
@@ -400,6 +400,9 @@
else new_snapshot.API.vM_memory_static_max (* new value is smaller
*) in
let new_snapshot = { new_snapshot with API.vM_memory_static_max =
new_mem } in
+ (* 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
+
let localhost = Helpers.get_localhost ~__context in
debug "%s phase 1/3: destroying old domain" api_call_name;
(* CA-13585: prevent glitch where power-state goes to Halted in the
middle of a reboot.
@@ -426,6 +429,7 @@
try
Vmops.start_paused
~progress_cb:(fun x -> TaskHelper.set_progress ~__context (0.50
+. x /. 2.))
+ ~pcidevs:(Some pcidevs)
~__context ~vm ~snapshot:new_snapshot;
with e ->
debug "Vmops.start_paused failed to create domain, setting VM %s
to Halted" (Ref.string_of vm);
diff -r 7ec163e4ed6c -r aacf1b563353 ocaml/xenops/device.ml
--- a/ocaml/xenops/device.ml Tue Jan 12 22:51:03 2010 +0000
+++ b/ocaml/xenops/device.ml Tue Jan 12 22:51:03 2010 +0000
@@ -1184,6 +1184,7 @@
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 plug ~xc ~xs (domain, bus, dev, func) domid devid =
let current = list ~xc ~xs domid in
let next_idx = List.fold_left max (-1) (List.map fst current) + 1 in
3 files changed, 27 insertions(+), 18 deletions(-)
ocaml/xapi/vmops.ml | 38 +++++++++++++++++++++-----------------
ocaml/xapi/xapi_vm.ml | 6 +++++-
ocaml/xenops/device.ml | 1 +
xen-api.hg-5.patch
Description: Text Data
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api
|