qemu: monitor: Add monitor infrastructure for 'snapshot-load' QMP command

Libvirt currently loads snapshots via the '-loadvm' commandline option
but that uses the same logic as the 'loadvm' text monitor command used
to pick the disk image with the 'vmstate' section. Since libvirt now
implements our own logic to pick the 'vmstate' device it can happen that
we pick a different than qemu and thus qemu would fail to load the
snapshot. This happens currently on VMs with UEFI firmware with NVRAM
image in qcow2 format.

To fix this libvirt will need to use the 'snapshot-load' QMP command
instead of relying on '-savevm'.

Implement the monitor bits for 'snapshot-load'.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Peter Krempa 2024-11-06 15:59:34 +01:00
parent c82dd60b2e
commit 2ed93e1a4b
4 changed files with 61 additions and 0 deletions

View File

@ -2780,6 +2780,22 @@ qemuMonitorSnapshotSave(qemuMonitor *mon,
}
int
qemuMonitorSnapshotLoad(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 qemuMonitorJSONSnapshotLoad(mon, jobname, snapshotname, vmstate_disk, disks);
}
int
qemuMonitorSnapshotDelete(qemuMonitor *mon,
const char *jobname,

View File

@ -1626,6 +1626,13 @@ qemuMonitorSnapshotSave(qemuMonitor *mon,
const char *vmstate_disk,
const char **disks);
int
qemuMonitorSnapshotLoad(qemuMonitor *mon,
const char *jobname,
const char *snapshotname,
const char *vmstate_disk,
const char **disks);
int
qemuMonitorSnapshotDelete(qemuMonitor *mon,
const char *jobname,

View File

@ -8754,6 +8754,37 @@ qemuMonitorJSONSnapshotSave(qemuMonitor *mon,
}
int
qemuMonitorJSONSnapshotLoad(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-load",
"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,

View File

@ -804,6 +804,13 @@ qemuMonitorJSONSnapshotSave(qemuMonitor *mon,
const char *vmstate_disk,
const char **disks);
int
qemuMonitorJSONSnapshotLoad(qemuMonitor *mon,
const char *jobname,
const char *snapshotname,
const char *vmstate_disk,
const char **disks);
int
qemuMonitorJSONSnapshotDelete(qemuMonitor *mon,
const char *jobname,