]> xenbits.xensource.com Git - xenclient/toolstack.git/commitdiff
refactor shutdown to work regardless of acpi_s_state
authorVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 10 Jun 2009 09:28:06 +0000 (10:28 +0100)
committerVincent Hanquez <vincent.hanquez@eu.citrix.com>
Wed, 10 Jun 2009 09:28:06 +0000 (10:28 +0100)
shutdown is now handling the difference between (different flavor of) hvm and pv,
instead of having shutdown completly useless in some case of hvm.
shutdown_ack now just call shutdown and wait the node to be remove for a PV domain.

xenops/domain.ml
xenops/domain.mli

index a29dd282324754b80e48458ddcec7bda13411e51..3274ed62e4d131821806a30c3a4a7c999d9286cf 100644 (file)
@@ -205,10 +205,19 @@ let hard_shutdown ~xc domid req =
 let control_shutdown ~xs domid = xs.Xs.getdomainpath domid ^ "/control/shutdown"
 
 (** Request a shutdown, return without waiting for acknowledgement *)
-let shutdown ~xs domid req =
+let shutdown ~xc ~xs ~hvm domid req =
        debug "Requesting shutdown of domain %d" domid;
        let reason = string_of_shutdown_reason req in
-       xs.Xs.write (control_shutdown ~xs domid) reason
+       xs.Xs.write (control_shutdown ~xs domid) reason;
+       if hvm then (
+               let has_pv_driver = Xc.hvm_check_pvdriver xc domid in
+               let acpi_s_state = Xc.domain_get_acpi_s_state xc domid in
+               (* If HVM domain has no PV drivers or is sleeping (according to acpi suspend state),
+                  we shut it down here using the shutdown hypercall. otherwise it shuts itself down
+                  but if doesn't remove the control/shutdown node *)
+               if not has_pv_driver || acpi_s_state <> 0 then
+                       Xc.domain_shutdown xc domid (shutdown_to_xc_shutdown req);
+       )
 
 (** PV domains will acknowledge the request by deleting the node from the
     store, block until this happens. *)
@@ -225,19 +234,14 @@ let shutdown_wait_for_ack ?timeout ~xs domid req =
 
 let shutdown_ack ?(timeout=60.) ~xc ~xs domid req =
        (* For both PV and HVM, write the control/shutdown node *)
-       shutdown ~xs domid req;
-       (* PV domains will acknowledge the request (if not then something
-          very bad is wrong) *)
-       if not ((Xc.domain_getinfo xc domid).Xc.hvm_guest)
-       then shutdown_wait_for_ack ~timeout ~xs domid req
-       else (
-               (* If HVM domain has no PV drivers, we shut it down here *)
-               if not(Xc.hvm_check_pvdriver xc domid)
-               then Xc.domain_shutdown xc domid (shutdown_to_xc_shutdown req);
-               (* If HVM domain has PV drivers, it shuts itself down but it
-                  doesn't remove the control/shutdown node. *)
+       let hvm = (Xc.domain_getinfo xc domid).Xc.hvm_guest in
+       shutdown ~xc ~xs ~hvm domid req;
+       if not hvm then
+               (* PV domains will acknowledge the request (if not then something
+                  very bad is wrong) *)
+               shutdown_wait_for_ack ~timeout ~xs domid req
+       else
                true
-       )
 
 let sysrq ~xs domid key =
        let path = xs.Xs.getdomainpath domid ^ "/control/sysrq" in
index 49d2616d200f69fab71d0aa4057ffa75012afe60..73b6a76a158d6ca25e4c10edaed9cd9940bc3cd2 100644 (file)
@@ -92,7 +92,7 @@ val shutdown_reason_of_int : int -> shutdown_reason
 val hard_shutdown: xc:Xc.handle -> domid -> shutdown_reason -> unit
 
 (** Tell the domain to shutdown with reason 'shutdown_reason'. Don't wait for an ack *)
-val shutdown: xs:Xs.xsh -> domid -> shutdown_reason -> unit
+val shutdown: xc:Xc.handle -> xs:Xs.xsh -> hvm:bool -> domid -> shutdown_reason -> unit
 
 (** Tell the domain to shutdown with reason ''shutdown_reason', waiting for an ack *)
 val shutdown_ack: ?timeout:float -> xc:Xc.handle -> xs:Xs.xsh -> domid -> shutdown_reason -> bool