]> xenbits.xensource.com Git - libvirt.git/commitdiff
snapshot: wire up new qemu monitor command
authorEric Blake <eblake@redhat.com>
Mon, 15 Aug 2011 23:25:54 +0000 (17:25 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 5 Sep 2011 13:03:05 +0000 (07:03 -0600)
No one uses this yet, but it will be important once
virDomainSnapshotCreateXML learns a VIR_DOMAIN_SNAPSHOT_DISK_ONLY
flag, and the xml allows passing in the new file names.

* src/qemu/qemu_monitor.h (qemuMonitorDiskSnapshot): New prototype.
* src/qemu/qemu_monitor_text.h (qemuMonitorTextDiskSnapshot):
Likewise.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONDiskSnapshot):
Likewise.
* src/qemu/qemu_monitor.c (qemuMonitorDiskSnapshot): New
function.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDiskSnapshot):
Likewise.

src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
src/qemu/qemu_monitor_text.c
src/qemu/qemu_monitor_text.h

index db6107c247e2e8e6b6ce74a05885470a3000639c..efc49c409ba573d75f8854f6b9fbd370e80103c4 100644 (file)
@@ -2391,6 +2391,30 @@ int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
     return ret;
 }
 
+/* Use the snapshot_blkdev command to convert the existing file for
+ * device into a read-only backing file of a new qcow2 image located
+ * at file.  */
+int
+qemuMonitorDiskSnapshot(qemuMonitorPtr mon, const char *device,
+                        const char *file)
+{
+    int ret;
+
+    VIR_DEBUG("mon=%p, device=%s, file=%s", mon, device, file);
+
+    if (!mon) {
+        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+                        _("monitor must not be NULL"));
+        return -1;
+    }
+
+    if (mon->json)
+        ret = qemuMonitorJSONDiskSnapshot(mon, device, file);
+    else
+        ret = qemuMonitorTextDiskSnapshot(mon, device, file);
+    return ret;
+}
+
 int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
                                 const char *cmd,
                                 char **reply,
index f241c9e4d3466165ef2d99a2c2b86c4e240f1449..b988a728d2992b4120f07179c4bcde0665100343 100644 (file)
@@ -447,6 +447,10 @@ int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorDiskSnapshot(qemuMonitorPtr mon,
+                            const char *device,
+                            const char *file);
+
 int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
                                 const char *cmd,
                                 char **reply,
index 4ceb5365381bf627b60c03a93fcd05f0c4d94c96..572cf3f08d47531dda65df75aec66a40d74b402a 100644 (file)
@@ -2703,6 +2703,39 @@ cleanup:
     return ret;
 }
 
+int
+qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, const char *device,
+                            const char *file)
+{
+    int ret;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    cmd = qemuMonitorJSONMakeCommand("snapshot-blkdev-sync",
+                                     "s:device", device,
+                                     "s:snapshot-file", file,
+                                     NULL);
+    if (!cmd)
+        return -1;
+
+    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+        goto cleanup;
+
+    if (qemuMonitorJSONHasError(reply, "CommandNotFound") &&
+        qemuMonitorCheckHMP(mon, "snapshot_blkdev")) {
+        VIR_DEBUG("snapshot-blkdev-sync command not found, trying HMP");
+        ret = qemuMonitorTextDiskSnapshot(mon, device, file);
+        goto cleanup;
+    }
+
+    ret = qemuMonitorJSONCheckError(cmd, reply);
+
+cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
 int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
                                     const char *cmd_str,
                                     char **reply_str,
index 9512793a30772230aea5b2a279537f499de08d13..a538e9ffc776143fe775724225319510a2bce228 100644 (file)
@@ -210,6 +210,10 @@ int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon,
+                                const char *device,
+                                const char *file);
+
 int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
                                     const char *cmd_str,
                                     char **reply_str,
index 854ee7f9f94fa539e56525fbc77eec84ed60653d..0e4bb7286084c5119313f5a57138a0c01c73842a 100644 (file)
@@ -2791,6 +2791,46 @@ cleanup:
     return ret;
 }
 
+int
+qemuMonitorTextDiskSnapshot(qemuMonitorPtr mon, const char *device,
+                            const char *file)
+{
+    char *cmd = NULL;
+    char *reply = NULL;
+    int ret = -1;
+    char *safename;
+
+    if (!(safename = qemuMonitorEscapeArg(file)) ||
+        virAsprintf(&cmd, "snapshot_blkdev %s \"%s\"", device, safename) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (qemuMonitorHMPCommand(mon, cmd, &reply)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("failed to take snapshot using command '%s'"), cmd);
+        goto cleanup;
+    }
+
+    if (strstr(reply, "error while creating qcow2") != NULL) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("Failed to take snapshot: %s"), reply);
+        goto cleanup;
+    }
+
+    /* XXX Should we scrape 'info block' output for
+     * 'device:... file=name backing_file=oldname' to make sure the
+     * command succeeded?  */
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(safename);
+    VIR_FREE(cmd);
+    VIR_FREE(reply);
+    return ret;
+}
+
 int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
                                     char **reply)
 {
index b2507382681eb5f61e35bc1d2c9bc31a1b384af9..55f78b48e1d0c2f3fd632be74be08bd3f429019d 100644 (file)
@@ -206,6 +206,10 @@ int qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name);
 int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
 
+int qemuMonitorTextDiskSnapshot(qemuMonitorPtr mon,
+                                const char *device,
+                                const char *file);
+
 int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
                                     char **reply);