Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_block.c | 121 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_block.h | 5 ++
src/qemu/qemu_driver.c | 123 +----------------------------------------
3 files changed, 127 insertions(+), 122 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index c0c4088cbf..5b34461853 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -3398,3 +3398,124 @@ qemuBlockCommit(virDomainObj *vm,
return -1;
}
+
+
+/* Called while holding the VM job lock, to implement a block job
+ * abort with pivot; this updates the VM definition as appropriate, on
+ * either success or failure. */
+int
+qemuBlockPivot(virDomainObj *vm,
+ qemuBlockJobData *job,
+ virDomainDiskDef *disk)
+{
+ g_autoptr(qemuBlockStorageSourceChainData) chainattachdata = NULL;
+ int ret = -1;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autoptr(virJSONValue) bitmapactions = NULL;
+ g_autoptr(virJSONValue) reopenactions = NULL;
+ int rc = 0;
+
+ if (job->state != QEMU_BLOCKJOB_STATE_READY) {
+ virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
+ _("block job '%s' not ready for pivot yet"),
+ job->name);
+ return -1;
+ }
+
+ switch ((qemuBlockJobType) job->type) {
+ case QEMU_BLOCKJOB_TYPE_NONE:
+ case QEMU_BLOCKJOB_TYPE_LAST:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("invalid job type '%d'"), job->type);
+ return -1;
+
+ case QEMU_BLOCKJOB_TYPE_PULL:
+ case QEMU_BLOCKJOB_TYPE_COMMIT:
+ case QEMU_BLOCKJOB_TYPE_BACKUP:
+ case QEMU_BLOCKJOB_TYPE_INTERNAL:
+ case QEMU_BLOCKJOB_TYPE_CREATE:
+ case QEMU_BLOCKJOB_TYPE_BROKEN:
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("job type '%s' does not support pivot"),
+ qemuBlockjobTypeToString(job->type));
+ return -1;
+
+ case QEMU_BLOCKJOB_TYPE_COPY:
+ if (!job->jobflagsmissing) {
+ bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
+ bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
+
+ bitmapactions = virJSONValueNewArray();
+
+ if (qemuMonitorTransactionBitmapAdd(bitmapactions,
+ disk->mirror->nodeformat,
+ "libvirt-tmp-activewrite",
+ false,
+ false,
+ 0) < 0)
+ return -1;
+
+ /* Open and install the backing chain of 'mirror' late if we can use
+ * blockdev-snapshot to do it. This is to appease oVirt that wants
+ * to copy data into the backing chain while the top image is being
+ * copied shallow */
+ if (reuse && shallow &&
+ virQEMUCapsGet(priv->qemuCaps,
QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY) &&
+ virStorageSourceHasBacking(disk->mirror)) {
+
+ if (!(chainattachdata =
qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->mirror->backingStore)))
+ return -1;
+
+ reopenactions = virJSONValueNewArray();
+
+ if (qemuMonitorTransactionSnapshotBlockdev(reopenactions,
+
disk->mirror->backingStore->nodeformat,
+
disk->mirror->nodeformat))
+ return -1;
+ }
+
+ }
+ break;
+
+ case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+ bitmapactions = virJSONValueNewArray();
+
+ if (qemuMonitorTransactionBitmapAdd(bitmapactions,
+ job->data.commit.base->nodeformat,
+ "libvirt-tmp-activewrite",
+ false,
+ false,
+ 0) < 0)
+ return -1;
+
+ break;
+ }
+
+ qemuDomainObjEnterMonitor(vm);
+
+ if (chainattachdata) {
+ if ((rc = qemuBlockStorageSourceChainAttach(priv->mon, chainattachdata)) == 0)
{
+ /* install backing images on success, or unplug them on failure */
+ if ((rc = qemuMonitorTransaction(priv->mon, &reopenactions)) != 0)
+ qemuBlockStorageSourceChainDetach(priv->mon, chainattachdata);
+ }
+ }
+
+ if (bitmapactions && rc == 0)
+ ignore_value(qemuMonitorTransaction(priv->mon, &bitmapactions));
+
+ if (rc == 0)
+ ret = qemuMonitorJobComplete(priv->mon, job->name);
+
+ qemuDomainObjExitMonitor(vm);
+
+ /* The pivot failed. The block job in QEMU remains in the synchronised state */
+ if (ret < 0)
+ return -1;
+
+ if (disk && disk->mirror)
+ disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT;
+ job->state = QEMU_BLOCKJOB_STATE_PIVOTING;
+
+ return ret;
+}
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index be81ec3c7f..d4b564e177 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -285,3 +285,8 @@ qemuBlockCommit(virDomainObj *vm,
const char *top,
unsigned long bandwidth,
unsigned int flags);
+
+int
+qemuBlockPivot(virDomainObj *vm,
+ qemuBlockJobData *job,
+ virDomainDiskDef *disk);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d353b6df93..564648f9ac 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14261,127 +14261,6 @@ qemuDomainOpenChannel(virDomainPtr dom,
}
-/* Called while holding the VM job lock, to implement a block job
- * abort with pivot; this updates the VM definition as appropriate, on
- * either success or failure. */
-static int
-qemuDomainBlockPivot(virDomainObj *vm,
- qemuBlockJobData *job,
- virDomainDiskDef *disk)
-{
- g_autoptr(qemuBlockStorageSourceChainData) chainattachdata = NULL;
- int ret = -1;
- qemuDomainObjPrivate *priv = vm->privateData;
- g_autoptr(virJSONValue) bitmapactions = NULL;
- g_autoptr(virJSONValue) reopenactions = NULL;
- int rc = 0;
-
- if (job->state != QEMU_BLOCKJOB_STATE_READY) {
- virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
- _("block job '%s' not ready for pivot yet"),
- job->name);
- return -1;
- }
-
- switch ((qemuBlockJobType) job->type) {
- case QEMU_BLOCKJOB_TYPE_NONE:
- case QEMU_BLOCKJOB_TYPE_LAST:
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid job type '%d'"), job->type);
- return -1;
-
- case QEMU_BLOCKJOB_TYPE_PULL:
- case QEMU_BLOCKJOB_TYPE_COMMIT:
- case QEMU_BLOCKJOB_TYPE_BACKUP:
- case QEMU_BLOCKJOB_TYPE_INTERNAL:
- case QEMU_BLOCKJOB_TYPE_CREATE:
- case QEMU_BLOCKJOB_TYPE_BROKEN:
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("job type '%s' does not support pivot"),
- qemuBlockjobTypeToString(job->type));
- return -1;
-
- case QEMU_BLOCKJOB_TYPE_COPY:
- if (!job->jobflagsmissing) {
- bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
- bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
-
- bitmapactions = virJSONValueNewArray();
-
- if (qemuMonitorTransactionBitmapAdd(bitmapactions,
- disk->mirror->nodeformat,
- "libvirt-tmp-activewrite",
- false,
- false,
- 0) < 0)
- return -1;
-
- /* Open and install the backing chain of 'mirror' late if we can use
- * blockdev-snapshot to do it. This is to appease oVirt that wants
- * to copy data into the backing chain while the top image is being
- * copied shallow */
- if (reuse && shallow &&
- virQEMUCapsGet(priv->qemuCaps,
QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY) &&
- virStorageSourceHasBacking(disk->mirror)) {
-
- if (!(chainattachdata =
qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->mirror->backingStore)))
- return -1;
-
- reopenactions = virJSONValueNewArray();
-
- if (qemuMonitorTransactionSnapshotBlockdev(reopenactions,
-
disk->mirror->backingStore->nodeformat,
-
disk->mirror->nodeformat))
- return -1;
- }
-
- }
- break;
-
- case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
- bitmapactions = virJSONValueNewArray();
-
- if (qemuMonitorTransactionBitmapAdd(bitmapactions,
- job->data.commit.base->nodeformat,
- "libvirt-tmp-activewrite",
- false,
- false,
- 0) < 0)
- return -1;
-
- break;
- }
-
- qemuDomainObjEnterMonitor(vm);
-
- if (chainattachdata) {
- if ((rc = qemuBlockStorageSourceChainAttach(priv->mon, chainattachdata)) == 0)
{
- /* install backing images on success, or unplug them on failure */
- if ((rc = qemuMonitorTransaction(priv->mon, &reopenactions)) != 0)
- qemuBlockStorageSourceChainDetach(priv->mon, chainattachdata);
- }
- }
-
- if (bitmapactions && rc == 0)
- ignore_value(qemuMonitorTransaction(priv->mon, &bitmapactions));
-
- if (rc == 0)
- ret = qemuMonitorJobComplete(priv->mon, job->name);
-
- qemuDomainObjExitMonitor(vm);
-
- /* The pivot failed. The block job in QEMU remains in the synchronised state */
- if (ret < 0)
- return -1;
-
- if (disk && disk->mirror)
- disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT;
- job->state = QEMU_BLOCKJOB_STATE_PIVOTING;
-
- return ret;
-}
-
-
/* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
* and not access it afterwards. */
static int
@@ -14544,7 +14423,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
qemuBlockJobSyncBegin(job);
if (pivot) {
- if ((ret = qemuDomainBlockPivot(vm, job, disk)) < 0)
+ if ((ret = qemuBlockPivot(vm, job, disk)) < 0)
goto endjob;
} else {
qemuDomainObjEnterMonitor(vm);
--
2.37.2