]> xenbits.xen.org Git - xenclient/toolstack.git/commitdiff
add pci hotplug capability in xenstore
authorVincent Hanquez <vincent.hanquez@eu.citrix.com>
Thu, 20 Aug 2009 08:25:21 +0000 (09:25 +0100)
committerVincent Hanquez <vincent.hanquez@eu.citrix.com>
Thu, 20 Aug 2009 08:25:21 +0000 (09:25 +0100)
also use the xenstore signal instead of the unix signal to signal ioemu.
patch from Dave Scott.

xenops/device.ml
xenops/device.mli
xenops/domain.ml

index 4daea8ac520be75daa0bd54037af7f98e512ac13..261f53b3e6899fea2a88d9b9c909bea3a0f1d8f0 100644 (file)
@@ -834,6 +834,10 @@ type t = {
 
 type dev = int * int * int * int
 
+let string_of_dev dev =
+       let (domain, bus, slot, func) = dev in
+       sprintf "%04x:%02x:%02x.%02x" domain bus slot func
+
 exception Cannot_add of dev list * exn (* devices, reason *)
 exception Cannot_use_pci_with_no_pciback of t list
 
@@ -1037,6 +1041,22 @@ let hard_shutdown ~xs (x: device) =
        debug "Device.Pci.hard_shutdown %s" (string_of_device x);
        clean_shutdown ~xs x
 
+let signal_device_model ~xc ~xs domid cmd parameter =
+       debug "Device.Pci.signal_device_model domid=%d cmd=%s param=%s" domid cmd parameter;
+       let dom0 = xs.Xs.getdomainpath 0 in (* XXX: assume device model is in domain 0 *)
+       Xs.transaction xs (fun t ->
+               t.Xst.writev dom0 [ Printf.sprintf "device-model/%d/command" domid, cmd;
+                                   Printf.sprintf "device-model/%d/parameter" domid, parameter ]
+       );
+       (* XXX: no response protocol *)
+       ()
+
+let plug ~xc ~xs (domain, bus, dev, func) domid devid =
+       signal_device_model ~xc ~xs domid "pci-ins" (Printf.sprintf "%.4x:%.2x:%.2x.%.1x" domain bus dev func)
+
+let unplug ~xc ~xs (domain, bus, dev, func) domid devid =
+       signal_device_model ~xc ~xs domid "pci-rem" (Printf.sprintf "%.4x:%.2x:%.2x.%.1x" domain bus dev func)
+
 end
 
 module Vfb = struct
@@ -1169,21 +1189,26 @@ let unlink_logfile domid = Unix.unlink (logfile domid)
 (* Where qemu writes its port number *)
 let vnc_port_path domid = sprintf "/local/domain/%d/console/vnc-port" domid
 
+(* Where qemu writes its state and is signalled *)
+let device_model_path domid = sprintf "/local/domain/0/device-model/%d" domid
+
 let power_mgmt_path domid = sprintf "/local/domain/0/device-model/%d/xen_extended_power_mgmt" domid
 let oem_features_path domid = sprintf "/local/domain/0/device-model/%d/oem_features" domid
 let inject_sci_path domid = sprintf "/local/domain/0/device-model/%d/inject-sci" domid
 
-let signal ~xs ~domid cmd param retexpected =
-       let cmdpath = sprintf "/local/domain/0/device-model/%d" domid in
+let signal ~xs ~domid ?wait_for ?param cmd =
+       let cmdpath = device_model_path domid in
        Xs.transaction xs (fun t ->
                t.Xst.write (cmdpath ^ "/command") cmd;
                match param with
                | None -> ()
                | Some param -> t.Xst.write (cmdpath ^ "/parameter") param
        );
-       let pw = cmdpath ^ "/state" in
-       Watch.wait_for ~xs (Watch.value_to_become pw retexpected);
-       ()
+       match wait_for with
+       | Some state ->
+               let pw = cmdpath ^ "/state" in
+               Watch.wait_for ~xs (Watch.value_to_become pw state)
+       | None -> ()
 
 (* Returns the allocated vnc port number *)
 let __start ~xs ~dmpath ~restore ?(timeout=qemu_dm_ready_timeout) info domid =
@@ -1311,6 +1336,11 @@ let __start ~xs ~dmpath ~restore ?(timeout=qemu_dm_ready_timeout) info domid =
 let start ~xs ~dmpath ?timeout info domid = __start ~xs ~restore:false ~dmpath ?timeout info domid
 let restore ~xs ~dmpath ?timeout info domid = __start ~xs ~restore:true ~dmpath ?timeout info domid
 
+
+(* suspend/resume is a done by sending signals to qemu *)
+let suspend ~xs domid = signal ~xs ~domid "save" ~wait_for:"paused"
+let resume ~xs domid = signal ~xs ~domid "continue" ~wait_for:"running"
+
 (* Called by every domain destroy, even non-HVM *)
 let stop ~xs domid signal =
        let qemu_pid_path = sprintf "/local/domain/%d/qemu-pid" domid in
@@ -1366,6 +1396,8 @@ let stop ~xs domid signal =
                           core files that bugtool will pick up; the xapi init script cleans out this directory with "rm -rf" on boot *)
                        (try Unix.rmdir ("/var/xen/qemu/"^(string_of_int qemu_pid)) with _ -> ())
                );
+               (try xs.Xs.rm (device_model_path domid) with _ -> ());
+
                (* Even if it's already dead (especially if it's already dead!) inspect the logfile *)
                begin try write_logfile_to_log domid
                with _ ->
index 55a308af44988dd0fef464d7fd6983a414e81a7f..e9d868496a6c4cc26ab95fef51b6efb6039e1752 100644 (file)
@@ -135,6 +135,8 @@ sig
               -> dev list -> Xc.domid -> int -> unit
        val reset : xs:Xs.xsh -> device -> unit
        val bind : dev list -> unit
+       val plug : xc:Xc.handle -> xs:Xs.xsh -> dev -> Xc.domid -> int -> unit
+       val unplug : xc:Xc.handle -> xs:Xs.xsh -> dev -> Xc.domid -> int -> unit
 end
 
 module Vfb :
@@ -178,10 +180,12 @@ sig
 
        val vnc_port_path : Xc.domid -> string
 
-       val signal : xs:Xs.xsh -> domid:Xc.domid
-                 -> string -> string option -> string -> unit
+       val signal : xs:Xs.xsh -> domid:Xc.domid -> ?wait_for:string -> ?param:string
+                 -> string -> unit
 
        val start : xs:Xs.xsh -> dmpath:string -> ?timeout:float -> info -> Xc.domid -> int
        val restore : xs:Xs.xsh -> dmpath:string -> ?timeout:float -> info -> Xc.domid -> int
+       val suspend : xs:Xs.xsh -> Xc.domid -> unit
+       val resume : xs:Xs.xsh -> Xc.domid -> unit
        val stop : xs:Xs.xsh -> Xc.domid -> int -> unit
 end
index 7b64d0f6a9837839b022e7b439c322a4ee5c1dd9..9d59679d70705588b01704fdb966ca932dcf8469 100644 (file)
@@ -772,7 +772,7 @@ let suspend ~xc ~xs ~hvm domid fd flags ?(progress_callback = fun _ -> ()) do_su
                do_suspend_callback ();
                if hvm then (
                        debug "Suspending qemu-dm for domid %d" domid;
-                       Device.Dm.stop ~xs domid Sys.sigusr1;
+                       Device.Dm.suspend ~xs domid;
                );
                XenguestHelper.send cnx "done\n";