mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
backup: Add new qemu monitor bitmap
The upcoming virDomainBackup() API needs to take advantage of various qcow2 bitmap manipulations as the basis to virDomainCheckpoints and incremental backups. Add four functions to expose block-dirty-bitmap-{add,enable,disable,merge} (this is the recently-added QEMU_CAPS_BITMAP_MERGE capability). Signed-off-by: Eric Blake <eblake@redhat.com> Acked-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
6abda7a445
commit
ad1c17c8d5
@ -4488,3 +4488,54 @@ qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
return qemuMonitorJSONGetCurrentMachineInfo(mon, info);
|
return qemuMonitorJSONGetCurrentMachineInfo(mon, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorAddBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap,
|
||||||
|
bool persistent)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("node=%s bitmap=%s persistent=%d", node, bitmap, persistent);
|
||||||
|
|
||||||
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
|
return qemuMonitorJSONAddBitmap(mon, node, bitmap, persistent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorEnableBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
|
||||||
|
|
||||||
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
|
return qemuMonitorJSONEnableBitmap(mon, node, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *dst,
|
||||||
|
virJSONValuePtr *src)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("node=%s dst=%s", node, dst);
|
||||||
|
|
||||||
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
|
return qemuMonitorJSONMergeBitmaps(mon, node, dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
|
||||||
|
|
||||||
|
QEMU_CHECK_MONITOR(mon);
|
||||||
|
|
||||||
|
return qemuMonitorJSONDeleteBitmap(mon, node, bitmap);
|
||||||
|
}
|
||||||
|
@ -646,6 +646,25 @@ int qemuMonitorSetBalloon(qemuMonitorPtr mon,
|
|||||||
unsigned long long newmem);
|
unsigned long long newmem);
|
||||||
int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online);
|
int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online);
|
||||||
|
|
||||||
|
int qemuMonitorAddBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap,
|
||||||
|
bool persistent)
|
||||||
|
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||||
|
int qemuMonitorEnableBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||||
|
int qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *dst,
|
||||||
|
virJSONValuePtr *src)
|
||||||
|
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
|
||||||
|
int qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||||
|
|
||||||
|
|
||||||
/* XXX should we pass the virDomainDiskDefPtr instead
|
/* XXX should we pass the virDomainDiskDefPtr instead
|
||||||
* and hide dev_name details inside monitor. Reconsider
|
* and hide dev_name details inside monitor. Reconsider
|
||||||
|
@ -8510,3 +8510,122 @@ qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
|
|||||||
virJSONValueFree(reply);
|
virJSONValueFree(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONAddBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap,
|
||||||
|
bool persistent)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
virJSONValuePtr cmd;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-add",
|
||||||
|
"s:node", node,
|
||||||
|
"s:name", bitmap,
|
||||||
|
"b:persistent", persistent,
|
||||||
|
NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
virJSONValuePtr cmd;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-enable",
|
||||||
|
"s:node", node,
|
||||||
|
"s:name", bitmap,
|
||||||
|
NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *dst,
|
||||||
|
virJSONValuePtr *src)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
virJSONValuePtr cmd;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-merge",
|
||||||
|
"s:node", node,
|
||||||
|
"s:target", dst,
|
||||||
|
"a:bitmaps", src,
|
||||||
|
NULL)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(*src);
|
||||||
|
*src = NULL;
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
virJSONValuePtr cmd;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-remove",
|
||||||
|
"s:node", node,
|
||||||
|
"s:name", bitmap,
|
||||||
|
NULL)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -580,5 +580,22 @@ int
|
|||||||
qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
|
qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
|
||||||
qemuMonitorCurrentMachineInfoPtr info)
|
qemuMonitorCurrentMachineInfoPtr info)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
int qemuMonitorJSONAddBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap,
|
||||||
|
bool persistent);
|
||||||
|
|
||||||
|
int qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap);
|
||||||
|
|
||||||
|
int qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *dst,
|
||||||
|
virJSONValuePtr *src);
|
||||||
|
|
||||||
|
int qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
|
||||||
|
const char *node,
|
||||||
|
const char *bitmap);
|
||||||
|
|
||||||
#endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
|
#endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
|
||||||
|
@ -1337,6 +1337,9 @@ GEN_TEST_FUNC(qemuMonitorJSONBlockdevTrayOpen, "foodev", true)
|
|||||||
GEN_TEST_FUNC(qemuMonitorJSONBlockdevTrayClose, "foodev")
|
GEN_TEST_FUNC(qemuMonitorJSONBlockdevTrayClose, "foodev")
|
||||||
GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumRemove, "foodev")
|
GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumRemove, "foodev")
|
||||||
GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumInsert, "foodev", "newnode")
|
GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumInsert, "foodev", "newnode")
|
||||||
|
GEN_TEST_FUNC(qemuMonitorJSONAddBitmap, "node", "bitmap", true)
|
||||||
|
GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap")
|
||||||
|
GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap")
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
|
testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
|
||||||
@ -1376,6 +1379,40 @@ testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
testQemuMonitorJSONqemuMonitorJSONMergeBitmaps(const void *opaque)
|
||||||
|
{
|
||||||
|
const testGenericData *data = opaque;
|
||||||
|
virDomainXMLOptionPtr xmlopt = data->xmlopt;
|
||||||
|
VIR_AUTOPTR(qemuMonitorTest) test = NULL;
|
||||||
|
VIR_AUTOPTR(virJSONValue) arr = NULL;
|
||||||
|
|
||||||
|
if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(arr = virJSONValueNewArray()))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virJSONValueArrayAppendString(arr, "b1") < 0 ||
|
||||||
|
virJSONValueArrayAppendString(arr, "b2") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddItem(test, "block-dirty-bitmap-merge",
|
||||||
|
"{\"return\":{}}") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONMergeBitmaps(qemuMonitorTestGetMonitor(test),
|
||||||
|
"node", "dst", &arr) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (arr) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "arr should have been cleared");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
testQemuMonitorJSONqemuMonitorJSONQueryCPUsEqual(struct qemuMonitorQueryCpusEntry *a,
|
testQemuMonitorJSONqemuMonitorJSONQueryCPUsEqual(struct qemuMonitorQueryCpusEntry *a,
|
||||||
struct qemuMonitorQueryCpusEntry *b)
|
struct qemuMonitorQueryCpusEntry *b)
|
||||||
@ -3019,6 +3056,9 @@ mymain(void)
|
|||||||
DO_TEST_GEN(qemuMonitorJSONBlockdevTrayClose);
|
DO_TEST_GEN(qemuMonitorJSONBlockdevTrayClose);
|
||||||
DO_TEST_GEN(qemuMonitorJSONBlockdevMediumRemove);
|
DO_TEST_GEN(qemuMonitorJSONBlockdevMediumRemove);
|
||||||
DO_TEST_GEN(qemuMonitorJSONBlockdevMediumInsert);
|
DO_TEST_GEN(qemuMonitorJSONBlockdevMediumInsert);
|
||||||
|
DO_TEST_GEN(qemuMonitorJSONAddBitmap);
|
||||||
|
DO_TEST_GEN(qemuMonitorJSONEnableBitmap);
|
||||||
|
DO_TEST_GEN(qemuMonitorJSONDeleteBitmap);
|
||||||
DO_TEST(qemuMonitorJSONGetBalloonInfo);
|
DO_TEST(qemuMonitorJSONGetBalloonInfo);
|
||||||
DO_TEST(qemuMonitorJSONGetBlockInfo);
|
DO_TEST(qemuMonitorJSONGetBlockInfo);
|
||||||
DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo);
|
DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo);
|
||||||
@ -3035,6 +3075,7 @@ mymain(void)
|
|||||||
DO_TEST(qemuMonitorJSONSendKeyHoldtime);
|
DO_TEST(qemuMonitorJSONSendKeyHoldtime);
|
||||||
DO_TEST(qemuMonitorSupportsActiveCommit);
|
DO_TEST(qemuMonitorSupportsActiveCommit);
|
||||||
DO_TEST(qemuMonitorJSONNBDServerStart);
|
DO_TEST(qemuMonitorJSONNBDServerStart);
|
||||||
|
DO_TEST(qemuMonitorJSONMergeBitmaps);
|
||||||
|
|
||||||
DO_TEST_CPU_DATA("host");
|
DO_TEST_CPU_DATA("host");
|
||||||
DO_TEST_CPU_DATA("full");
|
DO_TEST_CPU_DATA("full");
|
||||||
|
Loading…
Reference in New Issue
Block a user