From 5d0773633a9933176fa6606bb4e73c7aea3ad8ad Mon Sep 17 00:00:00 2001 From: Nikolai Barybin via Devel Date: Wed, 17 Jul 2024 21:21:35 +0300 Subject: [PATCH] qemu: monitor: Add plumbing for 'snaphot-save'/'snapshot-delete' QMP commands Signed-off-by: Nikolai Barybin Signed-off-by: Peter Krempa Reviewed-by: Pavel Hrdina --- src/qemu/qemu_monitor.c | 30 ++++++++++++++++++ src/qemu/qemu_monitor.h | 14 +++++++++ src/qemu/qemu_monitor_json.c | 60 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 13 ++++++++ tests/qemumonitorjsontest.c | 33 ++++++++++++++++++++ 5 files changed, 150 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index ada3de474f..fd888e2468 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2764,6 +2764,36 @@ qemuMonitorDeleteSnapshot(qemuMonitor *mon, const char *name) } +int +qemuMonitorSnapshotSave(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char *vmstate_disk, + const char **disks) +{ + VIR_DEBUG("jobname='%s', snapshotname='%s', vmstate_disk='%s'", + jobname, snapshotname, vmstate_disk); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONSnapshotSave(mon, jobname, snapshotname, vmstate_disk, disks); +} + + +int +qemuMonitorSnapshotDelete(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char **disks) +{ + VIR_DEBUG("jobname='%s', snapshotname='%s'", jobname, snapshotname); + + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONSnapshotDelete(mon, jobname, snapshotname, disks); +} + + int qemuMonitorBlockdevMirror(qemuMonitor *mon, const char *jobname, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 2bb64dd53f..6251f48d28 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1618,3 +1618,17 @@ int qemuMonitorDisplayReload(qemuMonitor *mon, const char *type, bool tlsCerts); + + +int +qemuMonitorSnapshotSave(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char *vmstate_disk, + const char **disks); + +int +qemuMonitorSnapshotDelete(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char **disks); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 75a5b03024..27f74181f6 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -8701,3 +8701,63 @@ int qemuMonitorJSONDisplayReload(qemuMonitor *mon, return 0; } + + +int +qemuMonitorJSONSnapshotSave(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char *vmstate_disk, + const char **disks) +{ + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; + g_autoptr(virJSONValue) devices = virJSONValueNewArray(); + + for (; *disks; disks++) { + if (virJSONValueArrayAppendString(devices, *disks) < 0) + return -1; + } + + if (!(cmd = qemuMonitorJSONMakeCommand("snapshot-save", + "s:job-id", jobname, + "s:tag", snapshotname, + "s:vmstate", vmstate_disk, + "a:devices", &devices, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + return qemuMonitorJSONCheckError(cmd, reply); +} + + +int +qemuMonitorJSONSnapshotDelete(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char **disks) +{ + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; + g_autoptr(virJSONValue) devices = virJSONValueNewArray(); + + for (; *disks; disks++) { + if (virJSONValueArrayAppendString(devices, *disks) < 0) + return -1; + } + + if (!(cmd = qemuMonitorJSONMakeCommand("snapshot-delete", + "s:job-id", jobname, + "s:tag", snapshotname, + "a:devices", &devices, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return -1; + + return qemuMonitorJSONCheckError(cmd, reply); +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index fef81fd911..10491b809b 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -825,3 +825,16 @@ qemuMonitorJSONQueryStats(qemuMonitor *mon, int qemuMonitorJSONDisplayReload(qemuMonitor *mon, const char *type, bool tlsCerts); + +int +qemuMonitorJSONSnapshotSave(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char *vmstate_disk, + const char **disks); + +int +qemuMonitorJSONSnapshotDelete(qemuMonitor *mon, + const char *jobname, + const char *snapshotname, + const char **disks); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index ab2c445289..fca4890746 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1217,6 +1217,38 @@ testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque) return 0; } + +static int +testQemuMonitorJSONqemuMonitorJSONSnapshot(const void *opaque) +{ + const testGenericData *data = opaque; + virDomainXMLOption *xmlopt = data->xmlopt; + g_autoptr(qemuMonitorTest) test = NULL; + const char *disks[] = { "test", "disk", NULL }; + + if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema))) + return -1; + + if (qemuMonitorTestAddItem(test, "snapshot-save", + "{\"return\":{}}") < 0) + return -1; + + if (qemuMonitorTestAddItem(test, "snapshot-delete", + "{\"return\":{}}") < 0) + return -1; + + if (qemuMonitorJSONSnapshotSave(qemuMonitorTestGetMonitor(test), + "jobname", "snapshotname", "vmstate", disks) < 0) + return -1; + + if (qemuMonitorJSONSnapshotDelete(qemuMonitorTestGetMonitor(test), + "jobname", "snapshotname", disks) < 0) + return -1; + + return 0; +} + + static bool testQemuMonitorJSONqemuMonitorJSONQueryCPUsEqual(struct qemuMonitorQueryCpusEntry *a, struct qemuMonitorQueryCpusEntry *b) @@ -2956,6 +2988,7 @@ mymain(void) DO_TEST(qemuMonitorJSONGetDumpGuestMemoryCapability); DO_TEST(qemuMonitorJSONSendKeyHoldtime); DO_TEST(qemuMonitorJSONNBDServerStart); + DO_TEST(qemuMonitorJSONSnapshot); DO_TEST_CPU_DATA("host"); DO_TEST_CPU_DATA("full");