mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-07 04:07:17 +00:00
qemu_process: abort snapshot delete when daemon starts
If the daemon crashes or is restarted while the snapshot delete is in progress we have to handle it gracefully to not leave any block jobs active. For now we will simply abort the snapshot delete operation so user can start it again. We need to refuse deleting external snapshots if there is already another active job as we would have to figure out which jobs we can abort. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
f474e80ac3
commit
cadbf40d05
@ -3692,6 +3692,42 @@ qemuProcessRecoverMigration(virQEMUDriver *driver,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuProcessAbortSnapshotDelete(virDomainObj *vm,
|
||||
virDomainJobObj *job)
|
||||
{
|
||||
size_t i;
|
||||
qemuDomainObjPrivate *priv = vm->privateData;
|
||||
qemuDomainJobPrivate *jobPriv = job->privateData;
|
||||
|
||||
if (!jobPriv->snapshotDelete)
|
||||
return;
|
||||
|
||||
for (i = 0; i < vm->def->ndisks; i++) {
|
||||
virDomainDiskDef *disk = vm->def->disks[i];
|
||||
g_autoptr(qemuBlockJobData) diskJob = qemuBlockJobDiskGetJob(disk);
|
||||
|
||||
if (!diskJob)
|
||||
continue;
|
||||
|
||||
if (diskJob->type != QEMU_BLOCKJOB_TYPE_COMMIT &&
|
||||
diskJob->type != QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qemuBlockJobSyncBegin(diskJob);
|
||||
|
||||
qemuDomainObjEnterMonitor(vm);
|
||||
ignore_value(qemuMonitorBlockJobCancel(priv->mon, diskJob->name, false));
|
||||
qemuDomainObjExitMonitor(vm);
|
||||
|
||||
diskJob->state = QEMU_BLOCKJOB_STATE_ABORTING;
|
||||
|
||||
qemuBlockJobSyncEnd(vm, diskJob, VIR_ASYNC_JOB_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuProcessRecoverJob(virQEMUDriver *driver,
|
||||
virDomainObj *vm,
|
||||
@ -3741,6 +3777,7 @@ qemuProcessRecoverJob(virQEMUDriver *driver,
|
||||
vm->def->name);
|
||||
}
|
||||
}
|
||||
qemuProcessAbortSnapshotDelete(vm, job);
|
||||
break;
|
||||
|
||||
case VIR_ASYNC_JOB_START:
|
||||
|
@ -3095,6 +3095,13 @@ qemuSnapshotDeleteValidate(virDomainObj *vm,
|
||||
}
|
||||
}
|
||||
|
||||
if (virDomainSnapshotIsExternal(snap) &&
|
||||
qemuDomainHasBlockjob(vm, false)) {
|
||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||
_("cannot delete external snapshots when there is another active block job"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virDomainSnapshotIsExternal(snap) &&
|
||||
!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
@ -3158,6 +3165,14 @@ qemuSnapshotDelete(virDomainObj *vm,
|
||||
* running to get everything we need. */
|
||||
delData = g_steal_pointer(&externalData);
|
||||
externalData = qemuSnapshotDeleteExternalPrepare(vm, snap);
|
||||
} else {
|
||||
qemuDomainJobPrivate *jobPriv = vm->job->privateData;
|
||||
|
||||
/* If the VM is running we need to indicate that the async snapshot
|
||||
* job is snapshot delete job. */
|
||||
jobPriv->snapshotDelete = true;
|
||||
|
||||
qemuDomainSaveStatus(vm);
|
||||
}
|
||||
|
||||
if (!externalData)
|
||||
|
Loading…
x
Reference in New Issue
Block a user