提交 b37fdfb9 编写于 作者: P Peter Krempa

backup: Store error message for failed backups

If a backup job fails midway it's hard to figure out what happened as
it's running asynchronous. Use the VIR_DOMAIN_JOB_ERRMSG job statistics
field to pass through the error from the first failed backup-blockjob
so that both the consumer of the virDomainGetJobStats and the
corresponding event can see the error.

event 'job-completed' for domain backup-test:
	operation: 9
	time_elapsed: 46
	disk_total: 104857600
	disk_processed: 10158080
	disk_remaining: 94699520
	success: 0
	errmsg: No space left on device

virsh domjobinfo backup-test --completed --anystats
Job type:         Failed
Operation:        Backup
Time elapsed:     46           ms
File processed:   9.688 MiB
File remaining:   90.312 MiB
File total:       100.000 MiB
Error message:    No space left on device

https://bugzilla.redhat.com/show_bug.cgi?id=1812827Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
上级 75a66f10
......@@ -65,6 +65,7 @@ virDomainBackupDefFree(virDomainBackupDefPtr def)
return;
g_free(def->incremental);
g_free(def->errmsg);
virStorageNetHostDefFree(1, def->server);
for (i = 0; i < def->ndisks; i++) {
......
......@@ -79,6 +79,8 @@ struct _virDomainBackupDef {
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 {
......
......@@ -650,6 +650,7 @@ qemuBackupJobTerminate(virDomainObjPtr vm,
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);
......@@ -951,6 +952,7 @@ void
qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
virDomainDiskDefPtr disk,
qemuBlockjobState state,
const char *errmsg,
unsigned long long cur,
unsigned long long end,
int asyncJob)
......@@ -964,8 +966,8 @@ qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
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;
......@@ -985,6 +987,10 @@ qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
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;
......
......@@ -38,6 +38,7 @@ void
qemuBackupNotifyBlockjobEnd(virDomainObjPtr vm,
virDomainDiskDefPtr disk,
qemuBlockjobState state,
const char *errmsg,
unsigned long long cur,
unsigned long long end,
int asyncJob);
......
......@@ -1435,7 +1435,7 @@ qemuBlockJobProcessEventConcludedBackup(virQEMUDriverPtr driver,
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 &&
......
......@@ -836,6 +836,10 @@ qemuDomainBackupJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册