#include "virthread.h"
#include "virtime.h"
#include "locking/domain_lock.h"
+#include "viralloc.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
diskPriv->blockJobType,
diskPriv->blockJobStatus);
diskPriv->blockJobStatus = -1;
+ VIR_FREE(diskPriv->blockJobError);
}
return status;
static virClassPtr qemuDomainDiskPrivateClass;
+static void qemuDomainDiskPrivateDispose(void *obj);
static int
qemuDomainDiskPrivateOnceInit(void)
qemuDomainDiskPrivateClass = virClassNew(virClassForObject(),
"qemuDomainDiskPrivate",
sizeof(qemuDomainDiskPrivate),
- NULL);
+ qemuDomainDiskPrivateDispose);
if (!qemuDomainDiskPrivateClass)
return -1;
else
return (virObjectPtr) priv;
}
+static void
+qemuDomainDiskPrivateDispose(void *obj)
+{
+ qemuDomainDiskPrivatePtr priv = obj;
+
+ VIR_FREE(priv->blockJobError);
+}
static virClassPtr qemuDomainStorageSourcePrivateClass;
static void qemuDomainStorageSourcePrivateDispose(void *obj);
/* for some synchronous block jobs, we need to notify the owner */
int blockJobType; /* type of the block job from the event */
int blockJobStatus; /* status of the finished block job */
+ char *blockJobError; /* block job completed event error */
bool blockJobSync; /* the block job needs synchronized termination */
bool migrating; /* the disk is being migrated */
qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
- int status)
+ int status,
+ const char *error)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, ret, domainBlockJob, mon->vm,
- diskAlias, type, status);
+ diskAlias, type, status, error);
return ret;
}
const char *diskAlias,
int type,
int status,
+ const char *error,
void *opaque);
typedef int (*qemuMonitorDomainTrayChangeCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
- int status);
+ int status,
+ const char *error);
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
{
const char *device;
const char *type_str;
+ const char *error = NULL;
int type = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
unsigned long long offset, len;
switch ((virConnectDomainEventBlockJobStatus) event) {
case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
+ error = virJSONValueObjectGetString(data, "error");
/* Make sure the whole device has been processed */
if (offset != len)
event = VIR_DOMAIN_BLOCK_JOB_FAILED;
}
out:
- qemuMonitorEmitBlockJob(mon, device, type, event);
+ qemuMonitorEmitBlockJob(mon, device, type, event, error);
}
static void
const char *diskAlias,
int type,
int status,
+ const char *error,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
/* We have a SYNC API waiting for this event, dispatch it back */
diskPriv->blockJobType = type;
diskPriv->blockJobStatus = status;
+ VIR_FREE(diskPriv->blockJobError);
+ ignore_value(VIR_STRDUP_QUIET(diskPriv->blockJobError, error));
virDomainObjBroadcast(vm);
} else {
/* there is no waiting SYNC API, dispatch the update to a thread */