From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:33398) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QM24p-0000P7-67 for qemu-devel@nongnu.org; Mon, 16 May 2011 13:59:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QM24n-0007Hw-RQ for qemu-devel@nongnu.org; Mon, 16 May 2011 13:59:31 -0400 Received: from e36.co.us.ibm.com ([32.97.110.154]:38522) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QM24n-0007Hp-DI for qemu-devel@nongnu.org; Mon, 16 May 2011 13:59:29 -0400 Received: from d03relay01.boulder.ibm.com (d03relay01.boulder.ibm.com [9.17.195.226]) by e36.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p4GHrerM013017 for ; Mon, 16 May 2011 11:53:40 -0600 Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by d03relay01.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p4GHx3Ds057662 for ; Mon, 16 May 2011 11:59:03 -0600 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p4GBx2JH013207 for ; Mon, 16 May 2011 05:59:02 -0600 From: Supriya Kannery Date: Mon, 16 May 2011 23:41:04 +0530 Message-Id: <20110516181104.7142.11570.sendpatchset@skannery> In-Reply-To: <20110516181023.7142.33402.sendpatchset@skannery> References: <20110516181023.7142.33402.sendpatchset@skannery> Subject: [Qemu-devel] [RFC Patch 3/3]Qemu: Add command "cache_set" for dynamic cache change List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Supriya Kannery , Christoph Hellwig , Prerna Saxena Add monitor command "cache_set" for dynamic cache change Signed-off-by: Christoph Hellwig Signed-off-by: Supriya Kannery --- block.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 2 ++ blockdev.c | 20 ++++++++++++++++++++ blockdev.h | 1 + hmp-commands.hx | 14 ++++++++++++++ qmp-commands.hx | 28 ++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+) Index: qemu/hmp-commands.hx =================================================================== --- qemu.orig/hmp-commands.hx +++ qemu/hmp-commands.hx @@ -70,6 +70,20 @@ but should be used with extreme caution. resizes image files, it can not resize block devices like LVM volumes. ETEXI + { + .name = "cache_set", + .args_type = "device:B,cache:s", + .params = "device cache", + .help = "change cache setting for device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_cache_set, + }, + +STEXI +@item cache_set +@findex cache_set +Change cache options for a block device while guest is running. +ETEXI { .name = "eject", Index: qemu/block.c =================================================================== --- qemu.orig/block.c +++ qemu/block.c @@ -657,6 +657,34 @@ unlink_and_fail: return ret; } +int bdrv_reopen(BlockDriverState *bs, int bdrv_flags) +{ + BlockDriver *drv = bs->drv; + int ret = 0; + + /* No need to reopen as no change in flags */ + if (bdrv_flags == bs->open_flags) { + return 0; + } + + /* Quiesce IO for the given block device */ + qemu_aio_flush(); + bdrv_flush(bs); + + bdrv_close(bs); + ret = bdrv_open(bs, bs->filename, bdrv_flags, drv); + + /* + * A failed attempt to reopen the image file must lead to 'abort()' + */ + if (ret != 0) { + qerror_report(QERR_REOPEN_FILE_FAILED, bs->filename); + abort(); + } + + return ret; +} + void bdrv_close(BlockDriverState *bs) { if (bs->drv) { @@ -3063,3 +3091,28 @@ out: return ret; } + +int bdrv_change_cache(BlockDriverState *bs, const char *cache) +{ + int bdrv_flags = 0; + + /* Clear cache flags */ + bdrv_flags = bs->open_flags & ~BDRV_O_CACHE_MASK; + + /* Set flags for requested cache setting */ + if (strcmp(cache, "writethrough")) { + if (!strcmp(cache, "off") || !strcmp(cache, "none")) { + bdrv_flags |= BDRV_O_NOCACHE; + } else if (!strcmp(cache, "writeback") || !strcmp(cache, "on")) { + bdrv_flags |= BDRV_O_CACHE_WB; + } else if (!strcmp(cache, "unsafe")) { + bdrv_flags |= BDRV_O_CACHE_WB; + bdrv_flags |= BDRV_O_NO_FLUSH; + } else { + error_report("invalid cache option"); + return -1; + } + } + + return(bdrv_reopen(bs, bdrv_flags)); +} Index: qemu/blockdev.c =================================================================== --- qemu.orig/blockdev.c +++ qemu/blockdev.c @@ -796,3 +796,23 @@ int do_block_resize(Monitor *mon, const return 0; } + +int do_cache_set(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + const char *device = qdict_get_str(qdict, "device"); + const char *cache = qdict_get_str(qdict, "cache"); + BlockDriverState *bs; + + bs = bdrv_find(device); + if (!bs) { + qerror_report(QERR_DEVICE_NOT_FOUND, device); + return -1; + } + + if(bdrv_is_inserted(bs)) { + return(bdrv_change_cache(bs, cache)); + } else { + qerror_report(QERR_DEVICE_NOT_INSERTED, device); + return -1; + } +} Index: qemu/block.h =================================================================== --- qemu.orig/block.h +++ qemu/block.h @@ -71,6 +71,7 @@ void bdrv_delete(BlockDriverState *bs); int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv); +int bdrv_reopen(BlockDriverState *bs, int bdrv_flags); void bdrv_close(BlockDriverState *bs); int bdrv_attach(BlockDriverState *bs, DeviceState *qdev); void bdrv_detach(BlockDriverState *bs, DeviceState *qdev); @@ -96,6 +97,7 @@ void bdrv_commit_all(void); int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file, const char *backing_fmt); void bdrv_register(BlockDriver *bdrv); +int bdrv_change_cache(BlockDriverState *bs, const char *cache); typedef struct BdrvCheckResult { Index: qemu/blockdev.h =================================================================== --- qemu.orig/blockdev.h +++ qemu/blockdev.h @@ -64,5 +64,6 @@ int do_change_block(Monitor *mon, const int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data); +int do_cache_set(Monitor *mon, const QDict *qdict, QObject **ret_data); #endif Index: qemu/qmp-commands.hx =================================================================== --- qemu.orig/qmp-commands.hx +++ qemu/qmp-commands.hx @@ -664,6 +664,34 @@ Example: -> { "execute": "block_resize", "arguments": { "device": "scratch", "size": 1073741824 } } <- { "return": {} } + +EQMP + + { + .name = "cache_set", + .args_type = "device:B,cache:s", + .params = "device cache", + .help = "change cache setting for device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_cache_set, + }, + +SQMP +cache_set +--------- + +Change cache setting while a guest is running. + +Arguments: + +- "device": the device's ID, must be unique (json-string) +- "cache": new cache string like none, writethrough etc.. (json-string) + +Example: + +-> { "execute": "cache_set", "arguments": { "device": "ide0-hd0", "cache": "writeback" } } +<- { "return": {} } + EQMP {