qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Prerna Saxena <prerna@linux.vnet.ibm.com>
To: qemu-devel <qemu-devel@nongnu.org>
Cc: kwolf@redhat.com, Anthony Liguori <aliguori@us.ibm.com>,
	Ananth Narayan <ananth@linux.vnet.ibm.com>,
	Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
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	[thread overview]
Message-ID: <20110228173757.7c34fd06@zephyr> (raw)
In-Reply-To: <20110228171956.05a84fb9@zephyr>

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
+@item set_cache
+@findex 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

  reply	other threads:[~2011-02-28 12:08 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28 11:49 [Qemu-devel] [RFC][PATCH 0/2] Allow cache settings for block devices to be changed at runtime Prerna Saxena
2011-02-28 12:07 ` Prerna Saxena [this message]
2011-02-28 12:11 ` [Qemu-devel] [RFC][PATCH 2/2] Extend monitor command 'info block' to display cache settings for block devices Prerna Saxena
2011-02-28 15:15   ` Kevin Wolf
2011-02-28 15:12 ` [Qemu-devel] [RFC][PATCH 0/2] Allow cache settings for block devices to be changed at runtime Kevin Wolf
2011-02-28 15:35   ` Stefan Hajnoczi
2011-02-28 15:48     ` Kevin Wolf
2011-03-01  9:55       ` Stefan Hajnoczi
2011-03-01 10:06         ` Kevin Wolf
2011-03-01 15:02           ` Chunqiang Tang
2011-03-01 13:03       ` Anthony Liguori
2011-03-01 13:22         ` Kevin Wolf
2011-03-01 15:47           ` Anthony Liguori
2011-03-01 12:42     ` Christoph Hellwig
2011-03-01 12:48       ` Stefan Hajnoczi
2011-03-01 12:50         ` Christoph Hellwig
2011-03-01 19:13           ` Anthony Liguori
2011-03-02  7:57             ` Kevin Wolf
2011-03-01 12:52       ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110228173757.7c34fd06@zephyr \
    --to=prerna@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=ananth@linux.vnet.ibm.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).