diff options
-rw-r--r-- | block.c | 16 | ||||
-rw-r--r-- | block.h | 1 | ||||
-rw-r--r-- | hmp.c | 2 | ||||
-rw-r--r-- | qapi-schema.json | 9 | ||||
-rw-r--r-- | qmp-commands.hx | 2 | ||||
-rw-r--r-- | scripts/qapi.py | 31 |
6 files changed, 48 insertions, 13 deletions
@@ -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) @@ -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); @@ -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): |