Daniel P. Berrange wrote:
This patch adds the public API for the virJobPtr object, and the
internal driver support code. The new public APIs are:
- int virJobGetInfo(virJobPtr job, virJobInfoPtr info);
This gets elapsed time, estimate completion time, completion
progress percentage, and completion status - success, failed,
cancelled.
- virDomainPtr virJobGetDomain(virJobPtr job);
If the job was a domain creation attempt, this gets the
resulting domain object
- virNetworkPtr virJobGetNetwork(virJobPtr job);
If the job was a network creation attempt, this gets the
resulting network object
- virErrorPtr virJobGetNetwork(virJobPtr job);
If the job failed, this gets the associated error
- int virJobCancel(virJobPtr job);
Request that the job be cancelled. This is not an immediate
operation. It merely sets a flag, which background jobs will
check periodically. So a job may still complete even if it
was cancelled. It should be responded to within a few seconds
though.
- int virJobDestroy(virJobPtr job);
Once a job has finished running (success, failed, or cancelled)
this may be called to release all resources associated with
the job.
As mentioned before, the following variants on existing APis are
added:
- virDomainCreateLinuxJob
- virDomainCreateJob
- virNetworkCreateJob
- virNetworkCreateXMLJob
- virDomainSaveJob
- virDomainRestoreJob
- virDomainDumpCoreJob
All are no-ops by default, unless the underlying driver supports
async jobs.
Finally, the job.c and job.h files provides a set of internal
routines to authors for the purpose of managing virJobPtr objects.
There is a default impl of the virJobDriver APIs which should be
suitable for all existing the remote driver. The async jobs are
basically run in a background pthread.
This psuedo code illustrates how the 'test' driver might use
these to implement an asynchronous variant of the 'save' method.
It basically stores the parameters in a struct, and then calls
the virJobCreate() method.
privdata = malloc(sizeof(*privdata));
if (privdata == NULL)
return (NULL);
memset(privdata, 0, sizeof(*privdata));
privdata->type = TEST_JOB_DOMAIN_SAVE;
privdata->data.save.domidx = domidx;
privdata->data.save.path = strdup(path);
job = virJobCreate(domain->conn,
domain->conn->driver->jobDriver,
testDomainSaveWorker,
NULL,
privdata,
VIR_JOB_BOUNDED);
The actual work is done in the 'testDomainSaveWorker' method
which is passed in to virJobCreate. The job.h file contains
APIs for it to call to update progress information and detect
cancellation:
static void testDomainSaveWorker(virJobPtr job, void *data)
{
testJobPtr privdata = data;
/* A 50 second ETA for saving */
virJobInitialize(job, 50);
do {
... do a unit of work...
... Check for cancellation ...
if (virJobFinishCancel(job))
return;
... update progress, indicating 1 second
of work complete, remove 1 second from
the ETA, and add 2% of completion state...
virJobUpdateRel(job, 1, -1, 2);
} while (...not done...);
... Inform world we're all done ...
virJobFinishSuccess(job);
}
The virJobInitialize, virJobFinishCancel, virJobFinishSuccess
and virJobUpdateRel methods all take care to lock the virJobPtr
object to ensure thread safety.
This API looks sensible.
I haven't checked the code in detail - I'll follow your Storage API
repository instead.
Rich.
--
Emerging Technologies, Red Hat -
http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903