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

Srivatsa S. Bhat srivatsa.bhat at linux.vnet.ibm.com
Mon Sep 12 09:25:26 UTC 2011


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.

-- 
Regards,
Srivatsa S. Bhat  <srivatsa.bhat at linux.vnet.ibm.com>
Linux Technology Center,
IBM India Systems and Technology Lab




More information about the libvir-list mailing list