aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c16
-rw-r--r--block.h1
-rw-r--r--hmp.c2
-rw-r--r--qapi-schema.json9
-rw-r--r--qmp-commands.hx2
-rw-r--r--scripts/qapi.py31
6 files changed, 48 insertions, 13 deletions
diff --git a/block.c b/block.c
index b38940bf85..24323c11d0 100644
--- a/block.c
+++ b/block.c
@@ -2450,6 +2450,9 @@ BlockInfoList *qmp_query_block(Error **errp)
info->value->inserted->backing_file = g_strdup(bs->backing_file);
}
+ info->value->inserted->backing_file_depth =
+ bdrv_get_backing_file_depth(bs);
+
if (bs->io_limits_enabled) {
info->value->inserted->bps =
bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
@@ -2754,6 +2757,19 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
return NULL;
}
+int bdrv_get_backing_file_depth(BlockDriverState *bs)
+{
+ if (!bs->drv) {
+ return 0;
+ }
+
+ if (!bs->backing_hd) {
+ return 0;
+ }
+
+ return 1 + bdrv_get_backing_file_depth(bs->backing_hd);
+}
+
#define NB_SUFFIXES 4
char *get_human_readable_size(char *buf, int buf_size, int64_t size)
diff --git a/block.h b/block.h
index c89590df4d..650d872f46 100644
--- a/block.h
+++ b/block.h
@@ -174,6 +174,7 @@ int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
int nb_sectors, int *pnum);
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
const char *backing_file);
+int bdrv_get_backing_file_depth(BlockDriverState *bs);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
int64_t bdrv_getlength(BlockDriverState *bs);
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
diff --git a/hmp.c b/hmp.c
index 6b72a64d99..25688ab0e2 100644
--- a/hmp.c
+++ b/hmp.c
@@ -227,6 +227,8 @@ void hmp_info_block(Monitor *mon)
if (info->value->inserted->has_backing_file) {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, info->value->inserted->backing_file);
+ monitor_printf(mon, " backing_file_depth=%" PRId64,
+ info->value->inserted->backing_file_depth);
}
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
info->value->inserted->ro,
diff --git a/qapi-schema.json b/qapi-schema.json
index e4a19cf2f8..cddf63a878 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -398,6 +398,8 @@
#
# @backing_file: #optional the name of the backing file (for copy-on-write)
#
+# @backing_file_depth: number of files in the backing file chain (since: 1.2)
+#
# @encrypted: true if the backing device is encrypted
#
# @bps: total throughput limit in bytes per second is specified
@@ -418,9 +420,10 @@
##
{ 'type': 'BlockDeviceInfo',
'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
- '*backing_file': 'str', 'encrypted': 'bool',
- 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
- 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
+ '*backing_file': 'str', 'backing_file_depth': 'int',
+ 'encrypted': 'bool', 'bps': 'int', 'bps_rd': 'int',
+ 'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int',
+ 'iops_wr': 'int'} }
##
# @BlockDeviceIoStatus:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index e3cf3c5a1a..ac466382c0 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1317,6 +1317,7 @@ Each json-object contain the following:
"nbd", "parallels", "qcow", "qcow2", "raw",
"tftp", "vdi", "vmdk", "vpc", "vvfat"
- "backing_file": backing file name (json-string, optional)
+ - "backing_file_depth": number of files in the backing file chain (json-int)
- "encrypted": true if encrypted, false otherwise (json-bool)
- "bps": limit total bytes per second (json-int)
- "bps_rd": limit read bytes per second (json-int)
@@ -1345,6 +1346,7 @@ Example:
"drv":"qcow2",
"encrypted":false,
"file":"disks/test.img",
+ "backing_file_depth":0,
"bps":1000000,
"bps_rd":0,
"bps_wr":0,
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8082af3fcd..d3b8b4d851 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -13,18 +13,29 @@ from ordereddict import OrderedDict
def tokenize(data):
while len(data):
- if data[0] in ['{', '}', ':', ',', '[', ']']:
- yield data[0]
- data = data[1:]
- elif data[0] in ' \n':
- data = data[1:]
- elif data[0] == "'":
- data = data[1:]
+ ch = data[0]
+ data = data[1:]
+ if ch in ['{', '}', ':', ',', '[', ']']:
+ yield ch
+ elif ch in ' \n':
+ None
+ elif ch == "'":
string = ''
- while data[0] != "'":
- string += data[0]
+ esc = False
+ while True:
+ if (data == ''):
+ raise Exception("Mismatched quotes")
+ ch = data[0]
data = data[1:]
- data = data[1:]
+ if esc:
+ string += ch
+ esc = False
+ elif ch == "\\":
+ esc = True
+ elif ch == "'":
+ break
+ else:
+ string += ch
yield string
def parse(tokens):