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(a)linux.vnet.ibm.com>
Linux Technology Center,
IBM India Systems and Technology Lab