[libvirt] [RFC] API to invoke S3/S4 on a KVM host and also resume from within libvirt

Vaidyanathan Srinivasan svaidy at linux.vnet.ibm.com
Mon Sep 19 05:56:08 UTC 2011


* Srivatsa S. Bhat <srivatsa.bhat at linux.vnet.ibm.com> [2011-09-12 14:55:26]:

> 
> Hi,
> 
> In order to exploit the host power management capabilities like S3/S4,
> it was proposed to add additional tags in the libvirt capabilities XML 
> to export the power management features supported by the host. The v5 of the RFC
> patch is here: http://www.redhat.com/archives/libvir-list/2011-August/msg00324.html.
> 
> It was also decided that it would be better to invoke S3/S4 and resume the host,
> from within libvirt, instead of doing it out-of-band. And it was agreed upon that
> an RTC wake up mechanism to resume the host from sleep would be best suited
> for doing the resume in-band. The discussion can be found here:
> http://www.redhat.com/archives/libvir-list/2011-August/msg00327.html
> 
> An API for this was initially discussed here:
> http://www.redhat.com/archives/libvir-list/2011-August/msg00248.html
> 
> One of the key challenges in implementing the API is that it has to return success
> to the caller before the host gets suspended, otherwise the connection will get 
> terminated and hence the status cannot be sent across to the caller. So to achieve
> this, we would need some kind of asynchronous mechanism.
> 
> Here are some ideas on how to go about doing this:
> 
> 1. Using the virCommandRunAsync() API to run the rtcwake command.
> 
> For example,
> 
> int virNodeSuspendForDuration(virConnectPtr conn, unsigned flags, long duration)
> {
>     virCommandPtr cmd;
> 
>     //Build up the rtcwake command with appropriate arguments, in 'cmd'
> 
>     virCommandRunAsync(cmd, NULL);
>     return 0; //Success
> }
> 
> Issues with this approach: 
> We cannot be sure that the node will not get suspended before returning
> the status to the caller.
> 
> 2. Using a timeout to delay the invocation of suspend. We can use a pre-exec-hook
>    to cause that delay.
> 
> For example,
> 
> int delay = 5; //in seconds
> 
> int virNodeSuspendForDuration(virConnectPtr conn, unsigned flags, long duration)
> {
>     virCommandPtr cmd;
> 
>     //Build up the rtcwake command with appropriate arguments, in 'cmd'
> 
>     virCommandSetPreExecHook(cmd, virNodeSuspendHook, &delay);
>     virCommandRunAsync(cmd, NULL);
>     return 0; //Success
> }
> 
> int virNodeSuspendHook(void *data)
> {
>     int *delay = data;
> 
>     /* Just delay for some time */
>     sleep(*delay);
>     return 0;
> }
> 
> Issues with this approach: 
> We may have to choose the delay value based on heuristics.
> But I don't see any serious downsides to this as long as the 
> delay is a suitably large value.
> 
> 
> Please let me know your suggestions.

Hi Sri,

The second approach of inserting a 5 sec delay may work better, the
caller will get status by then.  However one problem is that we need
to block all further commands to libvirt during this 5sec interval.
It is expected the caller will not issue any command to interfere with
the state.  What will happen if suspend is called twice or retried by
mistake?  The second suspend should not get queued and be invoked
after a resume.  So we need to track a global state where system is
flagged to enter suspend.

Also in virNodeSuspendForDuration()  there should be two parts, the
first part sets the RTC timer, this can be synchronous.  The second
part is invoking suspend, this is where you will use the
virCommandRunAsync() command.

--Vaidy





More information about the libvir-list mailing list