All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.