qemu: block: Ensure that <dataStore> is in appropriate state

In contrast to normal backing chain members where qemu does honour the
'auto-read-only' property the 'data-file' nodes are not automatically
reopened by qemu. Libvirt now has the infrastructure to reopen them
explicitly so use it for all transitions of the 'commit' block job.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Peter Krempa 2024-11-26 09:12:01 +01:00
parent ed656f4c8f
commit 754ca45c45
2 changed files with 47 additions and 2 deletions

View File

@ -3696,6 +3696,15 @@ qemuBlockCommit(virDomainObj *vm,
false, false, false) < 0)
goto cleanup;
if (baseSource->dataFileStore) {
if (qemuDomainStorageSourceAccessAllow(driver, vm, baseSource->dataFileStore,
false, false, false) < 0)
goto cleanup;
if (qemuBlockReopenReadWrite(vm, baseSource->dataFileStore, asyncJob) < 0)
goto cleanup;
}
if (top_parent && top_parent != disk->src) {
/* While top_parent is topmost image, we don't need to remember its
* owner as it will be overwritten upon finishing the commit. Hence,
@ -3703,6 +3712,15 @@ qemuBlockCommit(virDomainObj *vm,
if (qemuDomainStorageSourceAccessAllow(driver, vm, top_parent,
false, false, false) < 0)
goto cleanup;
if (top_parent->dataFileStore) {
if (qemuDomainStorageSourceAccessAllow(driver, vm, top_parent->dataFileStore,
false, false, false) < 0)
goto cleanup;
if (qemuBlockReopenReadWrite(vm, top_parent->dataFileStore, asyncJob) < 0)
goto cleanup;
}
}
if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
@ -3748,12 +3766,25 @@ qemuBlockCommit(virDomainObj *vm,
if (rc < 0 && clean_access) {
virErrorPtr orig_err;
virErrorPreserveLast(&orig_err);
/* Revert access to read-only, if possible. */
if (baseSource->dataFileStore) {
qemuDomainStorageSourceAccessAllow(driver, vm, baseSource->dataFileStore,
true, false, false);
qemuBlockReopenReadOnly(vm, baseSource->dataFileStore, asyncJob);
}
qemuDomainStorageSourceAccessAllow(driver, vm, baseSource,
true, false, false);
if (top_parent && top_parent != disk->src)
if (top_parent && top_parent != disk->src) {
if (top_parent->dataFileStore) {
qemuDomainStorageSourceAccessAllow(driver, vm, top_parent->dataFileStore,
true, false, false);
qemuBlockReopenReadWrite(vm, top_parent->dataFileStore, asyncJob);
}
qemuDomainStorageSourceAccessAllow(driver, vm, top_parent,
true, false, false);
}
virErrorRestore(&orig_err);
}

View File

@ -1064,11 +1064,25 @@ qemuBlockJobProcessEventCompletedCommit(virQEMUDriver *driver,
return;
/* revert access to images */
if (job->data.commit.base->dataFileStore) {
qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base->dataFileStore,
true, false, false);
qemuBlockReopenReadOnly(vm, job->data.commit.base->dataFileStore, asyncJob);
}
qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.base,
true, false, false);
if (job->data.commit.topparent != job->disk->src)
if (job->data.commit.topparent != job->disk->src) {
if (job->data.commit.topparent->dataFileStore) {
qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent->dataFileStore,
true, false, false);
qemuBlockReopenReadWrite(vm, job->data.commit.topparent->dataFileStore, asyncJob);
}
qemuDomainStorageSourceAccessAllow(driver, vm, job->data.commit.topparent,
true, false, true);
}
baseparent->backingStore = NULL;
job->data.commit.topparent->backingStore = job->data.commit.base;