[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 1/2] Add monitor command 'set-cache' to change
From: |
Prerna Saxena |
Subject: |
[Qemu-devel] [RFC][PATCH 1/2] Add monitor command 'set-cache' to change cache settings for a block device. |
Date: |
Mon, 28 Feb 2011 17:37:57 +0530 |
Usage :
(qemu) set_cache DEVICE CACHE-MODE
where CACHE-MODE can be one of writeback/ writethrough/ none.
At present, the image file is closed and re-opened with appropriate flags.
It might potentially cause problems if the underlying image is deleted
while a running qemu instance is using it. A change in cache operations
will cause the image file to be closed, and a deleted file will be gone.
Suggestions to fix this ?
---
blockdev.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
blockdev.h | 1 +
hmp-commands.hx | 13 +++++++++
3 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 0690cc8..6735205 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -636,6 +636,82 @@ out:
return ret;
}
+int do_set_cache(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;
+ BlockDriver *drv;
+ int ret = 0;
+ int bdrv_flags = 0;
+
+ if (!cache) {
+ /* TODO: in the absence of a change request,
+ simply display current cache setting.
+ Currently one needs 'info block' to query this */
+ qerror_report(QERR_MISSING_PARAMETER, "cache");
+ return -1;
+ }
+
+ bs = bdrv_find(device);
+ if (!bs) {
+ qerror_report(QERR_DEVICE_NOT_FOUND, device);
+ return -1;
+ }
+
+ /* Clear old flags */
+ bdrv_flags = bs->open_flags;
+ if (bdrv_flags & BDRV_O_CACHE_MASK) {
+ bdrv_flags &= ~BDRV_O_CACHE_MASK;
+ }
+
+ /* Determine flags for requested cache setting */
+ if (!strcmp(cache, "none")) {
+ bdrv_flags |= BDRV_O_NOCACHE;
+ } else if (!strcmp(cache, "writeback")) {
+ bdrv_flags |= BDRV_O_CACHE_WB;
+ } else if (!strcmp(cache, "unsafe")) {
+ /* TODO : Support unsafe mode */
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, cache,
+ "writeback, writethrough, none");
+ return -1;
+ } else if (!strcmp(cache, "writethrough")) {
+ /* Default setting */
+ } else {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, cache,
+ "'cache' must be one of writeback, writethrough, none");
+ return -1;
+ }
+
+ /* Verify that the cache setting specified is different from current.
+ * Does NOT call for error return, since the 'request' is already
+ * honoured.
+ */
+ if (bdrv_flags == bs->open_flags) {
+ qerror_report(QERR_PROPERTY_VALUE_IN_USE, device, "cache", cache);
+ return 0;
+ }
+
+ /* Quiesce IO for the given block device */
+ qemu_aio_flush();
+ bdrv_flush(bs);
+
+ /* Change cache value and restart IO on the block device */
+ printf("Setting cache=%s for device %s [ filename %s ]", cache, device,
+ bs->filename );
+ drv = bs->drv;
+ 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) {
+ abort();
+ }
+
+ return ret;
+}
+
static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
{
if (!force) {
diff --git a/blockdev.h b/blockdev.h
index 2c9e780..9f35817 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -63,6 +63,7 @@ int do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt);
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_set_cache(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data);
#endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 372bef4..18761cf 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1066,7 +1066,20 @@ STEXI
@findex watchdog_action
Change watchdog action.
ETEXI
+ {
+ .name = "set_cache",
+ .args_type = "device:B,cache:s",
+ .params = "device writeback|writethrough|none",
+ .help = "change cache settings for device",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = do_set_cache,
+ },
+STEXI
address@hidden set_cache
address@hidden set_cache
+Set cache options for a block device.
+ETEXI
{
.name = "acl_show",
.args_type = "aclname:s",
--
1.7.2.3
--
Prerna Saxena
Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India