From: Vincent Hanquez Date: Wed, 10 Jun 2009 09:28:06 +0000 (+0100) Subject: refactor shutdown to work regardless of acpi_s_state X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=ad02ec46a1d938612e60e54c87a24ff0f39fe49b;p=xenclient%2Ftoolstack.git refactor shutdown to work regardless of acpi_s_state 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. --- diff --git a/xenops/domain.ml b/xenops/domain.ml index a29dd28..3274ed6 100644 --- a/xenops/domain.ml +++ b/xenops/domain.ml @@ -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 diff --git a/xenops/domain.mli b/xenops/domain.mli index 49d2616..73b6a76 100644 --- a/xenops/domain.mli +++ b/xenops/domain.mli @@ -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