[libvirt] [PATCH v7 6/6] qemu: Support mountpoints option of guest-fsfreeze-freeze

Tomoki Sekiyama tomoki.sekiyama at hds.com
Fri May 2 00:06:19 UTC 2014


With this patch, virDomainFSFreeze will pass the mountpoints argument
to qemu guest agent. For example,

  virDomainFSFreeze(dom, {"/mnt/vol1", "/mnt/vol2"}, 2, 0)

will issue qemu guest agent command:

  {"execute":"guest-fsfreeze-freeze",
   "arguments":{"mountpoints":["/mnt/vol1","/mnt/vol2"]}}

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama at hds.com>
Acked-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/qemu/qemu_agent.c  |   47 +++++++++++++++++++++++++++++++++++++++++++----
 src/qemu/qemu_agent.h  |    3 ++-
 src/qemu/qemu_driver.c |   16 ++++++----------
 tests/qemuagenttest.c  |    8 +++++---
 4 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 4082331..57c7cc5 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -1235,6 +1235,32 @@ qemuAgentMakeCommand(const char *cmdname,
     return NULL;
 }
 
+static virJSONValuePtr
+qemuAgentMakeStringsArray(const char **strings, unsigned int len)
+{
+    size_t i;
+    virJSONValuePtr ret = virJSONValueNewArray(), str;
+
+    if (!ret)
+        return NULL;
+
+    for (i = 0; i < len; i++) {
+        str = virJSONValueNewString(strings[i]);
+        if (!str)
+            goto error;
+
+        if (virJSONValueArrayAppend(ret, str) < 0) {
+            virJSONValueFree(str);
+            goto error;
+        }
+    }
+    return ret;
+
+ error:
+    virJSONValueFree(ret);
+    return NULL;
+}
+
 void qemuAgentNotifyEvent(qemuAgentPtr mon,
                           qemuAgentEvent event)
 {
@@ -1287,21 +1313,34 @@ int qemuAgentShutdown(qemuAgentPtr mon,
 /*
  * qemuAgentFSFreeze:
  * @mon: Agent
+ * @mountpoints: Array of mountpoint paths to be frozen, or NULL for all
+ * @nmountpoints: Number of mountpoints to be frozen, or 0 for all
  *
  * Issue guest-fsfreeze-freeze command to guest agent,
- * which freezes all mounted file systems and returns
+ * which freezes file systems mounted on specified mountpoints
+ * (or all file systems when @mountpoints is NULL), and returns
  * number of frozen file systems on success.
  *
  * Returns: number of file system frozen on success,
  *          -1 on error.
  */
-int qemuAgentFSFreeze(qemuAgentPtr mon)
+int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints,
+                      unsigned int nmountpoints)
 {
     int ret = -1;
-    virJSONValuePtr cmd;
+    virJSONValuePtr cmd, arg;
     virJSONValuePtr reply = NULL;
 
-    cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL);
+    if (mountpoints && nmountpoints) {
+        arg = qemuAgentMakeStringsArray(mountpoints, nmountpoints);
+        if (!arg)
+            return -1;
+
+        cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze",
+                                   "a:mountpoints", arg, NULL);
+    } else {
+        cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL);
+    }
 
     if (!cmd)
         return -1;
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 5fbacdb..58531d5 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -70,7 +70,8 @@ typedef enum {
 int qemuAgentShutdown(qemuAgentPtr mon,
                       qemuAgentShutdownMode mode);
 
-int qemuAgentFSFreeze(qemuAgentPtr mon);
+int qemuAgentFSFreeze(qemuAgentPtr mon,
+                      const char **mountpoints, unsigned int nmountpoints);
 int qemuAgentFSThaw(qemuAgentPtr mon);
 
 int qemuAgentSuspend(qemuAgentPtr mon,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3a0334e..e523535 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12065,7 +12065,9 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver,
  * returned, FSThaw should be called revert the quiesced status. */
 static int
 qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver,
-                           virDomainObjPtr vm)
+                           virDomainObjPtr vm,
+                           const char **mountpoints,
+                           unsigned int nmountpoints)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverConfigPtr cfg;
@@ -12091,7 +12093,7 @@ qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver,
     virObjectUnref(cfg);
 
     qemuDomainObjEnterAgent(vm);
-    freezed = qemuAgentFSFreeze(priv->agent);
+    freezed = qemuAgentFSFreeze(priv->agent, mountpoints, nmountpoints);
     qemuDomainObjExitAgent(vm);
     return freezed < 0 ? -2 : freezed;
 }
@@ -13138,7 +13140,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
      * The command will fail if the guest is paused or the guest agent
      * is not running, or is already quiesced.  */
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) {
-        int freeze = qemuDomainSnapshotFSFreeze(driver, vm);
+        int freeze = qemuDomainSnapshotFSFreeze(driver, vm, NULL, 0);
         if (freeze < 0) {
             /* the helper reported the error */
             if (freeze == -2)
@@ -16539,12 +16541,6 @@ qemuDomainFSFreeze(virDomainPtr dom,
 
     virCheckFlags(0, -1);
 
-    if (mountpoints || nmountpoints) {
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("specifying mountpoints is not supported"));
-        return ret;
-    }
-
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
@@ -16560,7 +16556,7 @@ qemuDomainFSFreeze(virDomainPtr dom,
         goto endjob;
     }
 
-    ret = qemuDomainSnapshotFSFreeze(driver, vm);
+    ret = qemuDomainSnapshotFSFreeze(driver, vm, mountpoints, nmountpoints);
     if (ret == -2) {
         qemuDomainSnapshotFSThaw(driver, vm, false);
         ret = -1;
diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c
index 1131d98..be207e8 100644
--- a/tests/qemuagenttest.c
+++ b/tests/qemuagenttest.c
@@ -36,6 +36,7 @@ testQemuAgentFSFreeze(const void *data)
 {
     virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
     qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
+    const char *mountpoints[] = {"/fs1", "/fs2", "/fs3", "/fs4", "/fs5"};
     int ret = -1;
 
     if (!test)
@@ -55,7 +56,8 @@ testQemuAgentFSFreeze(const void *data)
                                "{ \"return\" : 7 }") < 0)
         goto cleanup;
 
-    if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
+    if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test),
+                                 mountpoints, 5)) < 0)
         goto cleanup;
 
     if (ret != 5) {
@@ -64,7 +66,7 @@ testQemuAgentFSFreeze(const void *data)
         goto cleanup;
     }
 
-    if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test))) < 0)
+    if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0)) < 0)
         goto cleanup;
 
     if (ret != 7) {
@@ -547,7 +549,7 @@ testQemuAgentTimeout(const void *data)
                                   NULL, NULL) < 0)
         goto cleanup;
 
-    if (qemuAgentFSFreeze(qemuMonitorTestGetAgent(test)) != -1) {
+    if (qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0) != -1) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        "agent command should have failed");
         goto cleanup;




More information about the libvir-list mailing list