From: Peter Krempa <[email protected]> Move the notification to the backup job after finishing the cleanup of the current block job the backup operation consists of.
Currently the termination of the blockjob would e.g. delete the scratch files before they are detached from qemu. In later patches the termination of the backup job may cause the qemu process to be killed (if the guest OS shut down but the qemu process was being kept alive to finish the backup) which would cause errors in the monitor commands for dismissing the block job. Since the NBD server still needs to be terminated first as otherwise the scratch files can't be unplugged from qemu we need to split the operation into two. First the NBD server is terminated, then the current block job is finalized and then the backup job is notified. Signed-off-by: Peter Krempa <[email protected]> --- src/qemu/qemu_backup.c | 41 +++++++++++++++++++++++++++------------- src/qemu/qemu_backup.h | 4 ++++ src/qemu/qemu_blockjob.c | 7 +++++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 9832c186a8..5eed35b471 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -981,6 +981,33 @@ qemuBackupGetXMLDesc(virDomainObj *vm, } +void +qemuBackupNotifyBlockjobEndStopNBD(virDomainObj *vm, + int asyncJob) +{ + qemuDomainObjPrivate *priv = vm->privateData; + virDomainBackupDef *backup = priv->backup; + + VIR_DEBUG("vm: '%s'", vm->def->name); + + if (!backup || + backup->type != VIR_DOMAIN_BACKUP_TYPE_PULL || + backup->nbdStopped) + return; + + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) + return; + ignore_value(qemuMonitorNBDServerStop(priv->mon)); + if (backup->tlsAlias) + ignore_value(qemuMonitorDelObject(priv->mon, backup->tlsAlias, false)); + if (backup->tlsSecretAlias) + ignore_value(qemuMonitorDelObject(priv->mon, backup->tlsSecretAlias, false)); + qemuDomainObjExitMonitor(vm); + + backup->nbdStopped = true; +} + + void qemuBackupNotifyBlockjobEnd(virDomainObj *vm, const char *diskdst, @@ -1005,20 +1032,8 @@ qemuBackupNotifyBlockjobEnd(virDomainObj *vm, if (!backup) return; + /* update the final statistics with the current job's data */ if (backup->type == VIR_DOMAIN_BACKUP_TYPE_PULL) { - if (!backup->nbdStopped) { - if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) - return; - ignore_value(qemuMonitorNBDServerStop(priv->mon)); - if (backup->tlsAlias) - ignore_value(qemuMonitorDelObject(priv->mon, backup->tlsAlias, false)); - if (backup->tlsSecretAlias) - ignore_value(qemuMonitorDelObject(priv->mon, backup->tlsSecretAlias, false)); - qemuDomainObjExitMonitor(vm); - backup->nbdStopped = true; - } - - /* update the final statistics with the current job's data */ backup->pull_tmp_used += cur; backup->pull_tmp_total += end; } else { diff --git a/src/qemu/qemu_backup.h b/src/qemu/qemu_backup.h index 768da6cbef..c259883bca 100644 --- a/src/qemu/qemu_backup.h +++ b/src/qemu/qemu_backup.h @@ -34,6 +34,10 @@ qemuBackupJobCancelBlockjobs(virDomainObj *vm, bool terminatebackup, int asyncJob); +void +qemuBackupNotifyBlockjobEndStopNBD(virDomainObj *vm, + int asyncJob); + void qemuBackupNotifyBlockjobEnd(virDomainObj *vm, const char *diskdst, diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 315b742053..b54a5b3811 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1392,8 +1392,7 @@ qemuBlockJobProcessEventConcludedBackup(virQEMUDriver *driver, if (job->disk) diskdst = job->disk->dst; - qemuBackupNotifyBlockjobEnd(vm, diskdst, newstate, job->errmsg, - progressCurrent, progressTotal, asyncJob); + qemuBackupNotifyBlockjobEndStopNBD(vm, asyncJob); if (job->data.backup.store && !(backend = qemuBlockStorageSourceDetachPrepare(job->data.backup.store))) @@ -1415,6 +1414,10 @@ qemuBlockJobProcessEventConcludedBackup(virQEMUDriver *driver, if (job->data.backup.store) qemuDomainStorageSourceAccessRevoke(driver, vm, job->data.backup.store); + + qemuBackupNotifyBlockjobEnd(vm, diskdst, newstate, job->errmsg, + progressCurrent, progressTotal, asyncJob); + } -- 2.51.1
