Implementing the VIR_DOMAIN_BLOCK_REBASE_SHALLOW flag will require
knowing what the immediate backing file is. As long as we don't
track the entire backing chain in <domain> XML, the next best that
we can do is to ask qemu.
* src/qemu/qemu_conf.h (qemuDomainDiskInfo): Add member.
* src/qemu/qemu_monitor.c (qemuMonitorGetBlockInfo): Free it, via...
(qemuMonitorBlockInfoFree): ...new helper.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONGetBlockInfo):
Populate it.
---
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_monitor.c | 10 +++++++++-
src/qemu/qemu_monitor_json.c | 12 ++++++++++++
3 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 482e6d3..a8aefaf 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -182,6 +182,7 @@ struct qemuDomainDiskInfo {
bool locked;
bool tray_open;
int io_status;
+ char *backing;
};
typedef virDomainObjPtr (*qemuDriverCloseCallback)(struct qemud_driver *driver,
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index f33bed8..2f5be2e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1358,6 +1358,14 @@ qemuMonitorBlockIOStatusToError(const char *status)
return -1;
}
+static void
+qemuMonitorBlockInfoFree(void *payload, const void *name ATTRIBUTE_UNUSED)
+{
+ struct qemuDomainDiskInfo *info = payload;
+ VIR_FREE(info->backing);
+ VIR_FREE(info);
+}
+
virHashTablePtr
qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
{
@@ -1372,7 +1380,7 @@ qemuMonitorGetBlockInfo(qemuMonitorPtr mon)
return NULL;
}
- if (!(table = virHashCreate(32, (virHashDataFree) free)))
+ if (!(table = virHashCreate(32, qemuMonitorBlockInfoFree)))
return NULL;
if (mon->json)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 3ddeaa3..d24d7e7 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1532,6 +1532,8 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
struct qemuDomainDiskInfo *info;
const char *thisdev;
const char *status;
+ virJSONValuePtr inserted;
+ const char *backing = NULL;
if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1584,6 +1586,16 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
if (info->io_status < 0)
goto cleanup;
}
+
+ /* Missing inserted, or inserted with missing backing_file,
+ * indicates no backing file. */
+ inserted = virJSONValueObjectGet(dev, "inserted");
+ if (inserted)
+ backing = virJSONValueObjectGetString(inserted, "backing_file");
+ if (backing && !(info->backing = strdup(backing))) {
+ virReportOOMError();
+ goto cleanup;
+ }
}
ret = 0;
--
1.7.7.6