[PATCHv2 15/16] blockjob: wire up online qemu block-commit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the bare minimum to kick off a block commit.  In particular,
flags support is missing (shallow requires us to crawl the backing
chain to determine the file name to pass to the qemu monitor command;
delete requires us to track what needs to be deleted at the time
the completion event fires).  Also, we are relying on qemu to do
error checking (such as validating 'top' and 'base' as being members
of the backing chain), including the fact that the current qemu code
does not support committing the active layer (although it is still
planned to add that before qemu 1.3).  Since the active layer won't
change, we have it easy and do not have to alter the domain XML.
Additionally, this will fail if SELinux is enforcing, because we fail
to grant qemu proper read/write access to the files it will modify.

* src/qemu/qemu_driver.c (qemuDomainBlockCommit): New function.
(qemuDriver): Register it.
---

Change from v1:
allow NULL top (let qemu reject it instead)
drop unused event variable

 src/qemu/qemu_driver.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6588b82..a9fd93a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12540,6 +12540,80 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth,
     return qemuDomainBlockRebase(dom, path, NULL, bandwidth, flags);
 }

+
+static int
+qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
+                      const char *top, unsigned long bandwidth,
+                      unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    qemuDomainObjPrivatePtr priv;
+    virDomainObjPtr vm = NULL;
+    char *device = NULL;
+    int ret = -1;
+    int idx;
+    virDomainDiskDefPtr disk;
+
+    virCheckFlags(0, -1);
+
+    if (!(vm = qemuDomObjFromDomain(dom)))
+        goto cleanup;
+    priv = vm->privateData;
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+        goto cleanup;
+
+    if (!virDomainObjIsActive(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       "%s", _("domain is not running"));
+        goto endjob;
+    }
+    if (!qemuCapsGet(priv->caps, QEMU_CAPS_BLOCK_COMMIT)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("online commit not supported with this QEMU binary"));
+        goto endjob;
+    }
+
+    device = qemuDiskPathToAlias(vm, path, &idx);
+    if (!device)
+        goto endjob;
+    disk = vm->def->disks[idx];
+
+    if (!disk->src) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("disk %s has no source file to be committed"),
+                       disk->dst);
+        goto endjob;
+    }
+
+    if (!top)
+        top = disk->src;
+
+    /* XXX For now, we are relying on qemu to check that 'top' and
+     * 'base' resolve to members of the backing chain in correct
+     * order; but if we ever get more paranoid and track the backing
+     * chain ourself, we should be pre-validating the data rather than
+     * relying on qemu.  For that matter, we need to be changing the
+     * SELinux label on both 'base' and the parent of 'top', so that
+     * qemu can open(O_RDWR) those files for the duration of the
+     * commit.  */
+    qemuDomainObjEnterMonitor(driver, vm);
+    ret = qemuMonitorBlockCommit(priv->mon, device, top, base, bandwidth);
+    qemuDomainObjExitMonitor(driver, vm);
+
+endjob:
+    if (qemuDomainObjEndJob(driver, vm) == 0) {
+        vm = NULL;
+        goto cleanup;
+    }
+
+cleanup:
+    VIR_FREE(device);
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
+
 static int
 qemuDomainOpenGraphics(virDomainPtr dom,
                        unsigned int idx,
@@ -13882,6 +13956,7 @@ static virDriver qemuDriver = {
     .domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */
     .domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */
     .domainBlockRebase = qemuDomainBlockRebase, /* 0.9.10 */
+    .domainBlockCommit = qemuDomainBlockCommit, /* 0.10.3 */
     .isAlive = qemuIsAlive, /* 0.9.8 */
     .nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */
     .domainSetBlockIoTune = qemuDomainSetBlockIoTune, /* 0.9.8 */
-- 
1.7.11.7

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]