Previously we were only starting or stopping nbdkit when the guest was
started or stopped or when hotplugging/unplugging a disk. But when doing
block operations, the disk backing store sources can also be be added or
removed independently of the disk device. When this happens the nbdkit
backend was not being handled properly. For example, when doing a
blockcopy from a nbdkit-backed disk to a new disk and pivoting to that
new location, the nbdkit process did not get cleaned up properly. Add
some functionality to qemuDomainStorageSourceAccessModify() to handle
this scenario.
Since we're now potentially starting nbdkit from another place in the
code, add a check to qemuNbdkitProcessStart() to report an error if we
are trying to start nbdkit for a disk source that already has a running
nbdkit process. This should never happen. If it does, it indicates an
error in another part of our code.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
---
src/qemu/qemu_domain.c | 10 ++++++++++
src/qemu/qemu_nbdkit.c | 7 +++++++
2 files changed, 17 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index de36641137..973a9af0b6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8026,6 +8026,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
bool revoke_namespace = false;
bool revoke_nvme = false;
bool revoke_lockspace = false;
+ bool revoke_nbdkit = false;
VIR_DEBUG("src='%s' readonly=%d force_ro=%d force_rw=%d revoke=%d
chain=%d",
NULLSTR(src->path), src->readonly, force_ro, force_rw, revoke,
chain);
@@ -8044,6 +8045,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
revoke_namespace = true;
revoke_nvme = true;
revoke_lockspace = true;
+ revoke_nbdkit = true;
ret = 0;
goto revoke;
}
@@ -8059,6 +8061,11 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
revoke_nvme = true;
+ if (qemuNbdkitStartStorageSource(driver, vm, src, chain) < 0)
+ goto revoke;
+
+ revoke_nbdkit = true;
+
if (qemuDomainNamespaceSetupDisk(vm, src, &revoke_namespace) < 0)
goto revoke;
}
@@ -8113,6 +8120,9 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
VIR_WARN("Unable to release lock on %s", srcstr);
}
+ if (revoke_nbdkit)
+ qemuNbdkitStopStorageSource(src, vm, chain);
+
cleanup:
src->readonly = was_readonly;
virErrorRestore(&orig_err);
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index edbe2137d0..73dc90af3e 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -1195,6 +1195,13 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
struct nbd_handle *nbd = NULL;
#endif
+ /* don't try to start nbdkit again if we've already started it */
+ if (proc->pid > 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Attempting to start nbdkit twice"));
+ return -1;
+ }
+
if (!(cmd = qemuNbdkitProcessBuildCommand(proc)))
return -1;
--
2.43.0