if (virCondInit(&priv->job.cond) < 0)
return -1;
+ if (VIR_ALLOC(priv->job.current) < 0)
+ return -1;
+
return 0;
}
libxlDomainObjFreeJob(libxlDomainObjPrivatePtr priv)
{
ignore_value(virCondDestroy(&priv->job.cond));
+ VIR_FREE(priv->job.current);
}
/* Give up waiting for mutex after 30 seconds */
VIR_DEBUG("Starting job: %s", libxlDomainJobTypeToString(job));
priv->job.active = job;
priv->job.owner = virThreadSelfID();
+ priv->job.started = now;
+ priv->job.current->type = VIR_DOMAIN_JOB_UNBOUNDED;
return 0;
return virObjectUnref(obj);
}
+int
+libxlDomainJobUpdateTime(struct libxlDomainJobObj *job)
+{
+ virDomainJobInfoPtr jobInfo = job->current;
+ unsigned long long now;
+
+ if (!job->started)
+ return 0;
+
+ if (virTimeMillisNow(&now) < 0)
+ return -1;
+
+ if (now < job->started) {
+ job->started = 0;
+ return 0;
+ }
+
+ jobInfo->timeElapsed = now - job->started;
+ return 0;
+}
+
static void *
libxlDomainObjPrivateAlloc(void)
{
virCond cond; /* Use to coordinate jobs */
enum libxlDomainJob active; /* Currently running job */
int owner; /* Thread which set current job */
+ unsigned long long started; /* When the job started */
+ virDomainJobInfoPtr current; /* Statistics for the current job */
};
typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
virDomainObjPtr obj)
ATTRIBUTE_RETURN_CHECK;
+int
+libxlDomainJobUpdateTime(struct libxlDomainJobObj *job)
+ ATTRIBUTE_RETURN_CHECK;
+
void
libxlDomainEventQueue(libxlDriverPrivatePtr driver,
virObjectEventPtr event);
#undef LIBXL_SET_MEMSTAT
+static int
+libxlDomainGetJobInfo(virDomainPtr dom,
+ virDomainJobInfoPtr info)
+{
+ libxlDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
+ int ret = -1;
+
+ if (!(vm = libxlDomObjFromDomain(dom)))
+ goto cleanup;
+
+ if (virDomainGetJobInfoEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ priv = vm->privateData;
+ if (!priv->job.active) {
+ memset(info, 0, sizeof(*info));
+ info->type = VIR_DOMAIN_JOB_NONE;
+ ret = 0;
+ goto cleanup;
+ }
+
+ /* In libxl we don't have an estimated completion time
+ * thus we always set to unbounded and update time
+ * for the active job. */
+ if (libxlDomainJobUpdateTime(&priv->job) < 0)
+ goto cleanup;
+
+ memcpy(info, priv->job.current, sizeof(virDomainJobInfo));
+ ret = 0;
+
+ cleanup:
+ if (vm)
+ virObjectUnlock(vm);
+ return ret;
+}
+
+
static int
libxlConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eventID,
virConnectDomainEventGenericCallback callback,
#endif
.nodeGetFreeMemory = libxlNodeGetFreeMemory, /* 0.9.0 */
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
+ .domainGetJobInfo = libxlDomainGetJobInfo, /* 1.3.1 */
.domainMemoryStats = libxlDomainMemoryStats, /* 1.3.0 */
.domainGetCPUStats = libxlDomainGetCPUStats, /* 1.3.0 */
.connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */