New command "block_set_hostcache" added for dynamically changing host pagecache setting of a block device.
Usage: block_set_hostcache <device> <option> <device> = block device <option> = on/off Example: (qemu) block_set_hostcache ide0-hd0 off Signed-off-by: Supriya Kannery <supri...@linux.vnet.ibm.com> --- Index: qemu/block.c =================================================================== --- qemu.orig/block.c +++ qemu/block.c @@ -970,6 +970,30 @@ void bdrv_close_all(void) } } +void bdrv_change_hostcache(BlockDriverState *bs, bool enable, Error **errp) +{ + int bdrv_flags = bs->open_flags; + + /* set hostcache flags (without changing WCE/flush bits) */ + if (enable) { + bdrv_flags &= ~BDRV_O_NOCACHE; + } else { + bdrv_flags |= BDRV_O_NOCACHE; + } + + /* If no change in flags, no need to reopen */ + if (bdrv_flags != bs->open_flags) { + if (bdrv_is_inserted(bs)) { + /* Reopen file with changed set of flags */ + bdrv_flags &= ~BDRV_O_CACHE_WB; + bdrv_reopen(bs, bdrv_flags, errp); + } else { + /* Save hostcache change for future use */ + bs->open_flags = bdrv_flags; + } + } +} + /* * Wait for pending requests to complete across all BlockDriverStates * Index: qemu/blockdev.c =================================================================== --- qemu.orig/blockdev.c +++ qemu/blockdev.c @@ -1191,3 +1191,22 @@ BlockJobInfoList *qmp_query_block_jobs(E bdrv_iterate(do_qmp_query_block_jobs_one, &prev); return dummy.next; } + +/* + * Change host page cache setting while guest is running. +*/ +void qmp_block_set_hostcache(const char *device, bool enable, + Error **errp) +{ + BlockDriverState *bs = NULL; + + /* Validate device */ + bs = bdrv_find(device); + if (!bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; + } + + bdrv_change_hostcache(bs, enable, errp); + return; +} Index: qemu/hmp-commands.hx =================================================================== --- qemu.orig/hmp-commands.hx +++ qemu/hmp-commands.hx @@ -1344,6 +1344,21 @@ passed since 1970, i.e. unix epoch. ETEXI { + .name = "block_set_hostcache", + .args_type = "device:B,option:b", + .params = "device on|off", + .help = "Change setting of host pagecache", + .mhandler.cmd = hmp_block_set_hostcache, + }, + +STEXI +@item block_set_hostcache @var{device} @var{option} +@findex block_set_hostcache +Change host pagecache setting of a block device while guest is running. +ETEXI + + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", Index: qemu/qmp-commands.hx =================================================================== --- qemu.orig/qmp-commands.hx +++ qemu/qmp-commands.hx @@ -987,6 +987,30 @@ Example: EQMP { + .name = "block_set_hostcache", + .args_type = "device:B,option:b", + .mhandler.cmd_new = qmp_marshal_input_block_set_hostcache, + }, + +SQMP +block_set_hostcache +------------------- + +Change host pagecache setting of a block device + +Arguments: + +- "device": the device's ID, must be unique (json-string) +- "option": hostcache setting (json-bool) + +Example: +-> { +"execute": "block_set_hostcache", "arguments": { "device": "ide0-hd0", "option": false } } +<- { "return": {} } + +EQMP + + + { .name = "set_password", .args_type = "protocol:s,password:s,connected:s?", .mhandler.cmd_new = qmp_marshal_input_set_password, Index: qemu/qapi-schema.json =================================================================== --- qemu.orig/qapi-schema.json +++ qemu/qapi-schema.json @@ -1604,6 +1604,23 @@ 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int' } } ## +# @block_set_hostcache: +# +# Change host pagecache setting of a block device +# +# @device: name of the block device +# +# @option: hostcache setting (true/false) +# +# Returns: Nothing on success +# If @device is not a valid block device, DeviceNotFound +# +# Since: 1.2 +## +{ 'command': 'block_set_hostcache', + 'data': { 'device': 'str', 'option': 'bool' } } + +## # @block-stream: # # Copy data from a backing file into a block device. Index: qemu/hmp.c =================================================================== --- qemu.orig/hmp.c +++ qemu/hmp.c @@ -837,6 +837,15 @@ void hmp_block_set_io_throttle(Monitor * hmp_handle_error(mon, &err); } +void hmp_block_set_hostcache(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + + qmp_block_set_hostcache(qdict_get_str(qdict, "device"), + qdict_get_bool(qdict, "option"), &err); + hmp_handle_error(mon, &err); +} + void hmp_block_stream(Monitor *mon, const QDict *qdict) { Error *error = NULL; Index: qemu/hmp.h =================================================================== --- qemu.orig/hmp.h +++ qemu/hmp.h @@ -66,5 +66,6 @@ void hmp_netdev_add(Monitor *mon, const void hmp_netdev_del(Monitor *mon, const QDict *qdict); void hmp_getfd(Monitor *mon, const QDict *qdict); void hmp_closefd(Monitor *mon, const QDict *qdict); +void hmp_block_set_hostcache(Monitor *mon, const QDict *qdict); #endif Index: qemu/block.h =================================================================== --- qemu.orig/block.h +++ qemu/block.h @@ -187,6 +187,7 @@ int bdrv_commit_all(void); int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file, const char *backing_fmt); void bdrv_register(BlockDriver *bdrv); +void bdrv_change_hostcache(BlockDriverState *bs, bool enable, Error **errp); typedef struct BdrvCheckResult {