unsigned long long push_total;
unsigned long long pull_tmp_used;
unsigned long long pull_tmp_total;
+
+ char *errmsg; /* error message of failed sub-blockjob */
};
typedef enum {
priv->job.completed->stats.backup.tmp_total = priv->backup->pull_tmp_total;
priv->job.completed->status = jobstatus;
+ priv->job.completed->errmsg = g_strdup(priv->backup->errmsg);
qemuDomainEventEmitJobCompleted(priv->driver, vm);
qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
virDomainDiskDefPtr disk,
qemuBlockjobState state,
+ const char *errmsg,
unsigned long long cur,
unsigned long long end,
int asyncJob)
virDomainBackupDefPtr backup = priv->backup;
size_t i;
- VIR_DEBUG("vm: '%s', disk:'%s', state:'%d'",
- vm->def->name, disk->dst, state);
+ VIR_DEBUG("vm: '%s', disk:'%s', state:'%d' errmsg:'%s'",
+ vm->def->name, disk->dst, state, NULLSTR(errmsg));
if (!backup)
return;
backup->push_total += end;
}
+ /* record first error message */
+ if (!backup->errmsg)
+ backup->errmsg = g_strdup(errmsg);
+
for (i = 0; i < backup->ndisks; i++) {
virDomainBackupDiskDefPtr backupdisk = backup->disks + i;
g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
g_autoptr(virJSONValue) actions = NULL;
- qemuBackupNotifyBlockjobEnd(vm, job->disk, newstate,
+ qemuBackupNotifyBlockjobEnd(vm, job->disk, newstate, job->errmsg,
progressCurrent, progressTotal, asyncJob);
if (job->data.backup.store &&
VIR_DOMAIN_JOB_SUCCESS) < 0)
return -1;
+ if (jobInfo->errmsg &&
+ virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) < 0)
+ return -1;
+
*nparams = virTypedParamListStealParams(par, params);
*type = qemuDomainJobStatusToType(jobInfo->status);
return 0;