From patchwork Mon Oct 26 14:25:16 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naphtali Sprei X-Patchwork-Id: 36910 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C1FD0B7BD7 for ; Tue, 27 Oct 2009 01:27:33 +1100 (EST) Received: from localhost ([127.0.0.1]:48273 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2QXi-0001ab-T9 for incoming@patchwork.ozlabs.org; Mon, 26 Oct 2009 10:27:30 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N2QVl-0000vX-AL for qemu-devel@nongnu.org; Mon, 26 Oct 2009 10:25:29 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N2QVg-0000ri-Ev for qemu-devel@nongnu.org; Mon, 26 Oct 2009 10:25:28 -0400 Received: from [199.232.76.173] (port=52896 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2QVg-0000ra-7P for qemu-devel@nongnu.org; Mon, 26 Oct 2009 10:25:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45174) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N2QVf-0003Rv-DL for qemu-devel@nongnu.org; Mon, 26 Oct 2009 10:25:23 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9QEPL5D028875 for ; Mon, 26 Oct 2009 10:25:21 -0400 Received: from [10.35.0.60] (dhcp-0-60.tlv.redhat.com [10.35.0.60]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9QEPHBj028754 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 26 Oct 2009 10:25:19 -0400 Message-ID: <4AE5B14C.5050101@redhat.com> Date: Mon, 26 Oct 2009 16:25:16 +0200 From: Naphtali Sprei User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 To: qemu-devel@nongnu.org X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Subject: [Qemu-devel] [PATCH v2] Added readonly flag to -drive command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This is a slightly revised patch for adding readonly flag to the -drive command. Even though this patch is "stand-alone", it assumes a previous related patch (in Anthony staging tree), that passes the readonly attribute of the drive to the guest OS, applied first. This enables sharing same image between guests, with readonly access. Implementaion mark the drive as read_only and changes the flags when actually opening the file. The readonly attribute of a qcow also passed to it's base file. For ide that cannot pass the readonly attribute to the guest OS, disallow the readonly flag. Also, return error code from bdrv_truncate for readonly drive. Signed-off-by: Naphtali Sprei --- block.c | 19 +++++++++++++++---- block.h | 1 + qemu-config.c | 3 +++ vl.c | 10 ++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index 33f3d65..cffd95e 100644 --- a/block.c +++ b/block.c @@ -331,11 +331,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags) int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { - int ret, open_flags; + int ret, open_flags, try_rw; char tmp_filename[PATH_MAX]; char backing_filename[PATH_MAX]; - bs->read_only = 0; bs->is_temporary = 0; bs->encrypted = 0; bs->valid_key = 0; @@ -422,9 +421,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, /* Note: for compatibility, we open disk image files as RDWR, and RDONLY as fallback */ + try_rw = !bs->read_only || bs->is_temporary; if (!(flags & BDRV_O_FILE)) - open_flags = BDRV_O_RDWR | - (flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO)); + open_flags = (try_rw ? BDRV_O_RDWR : 0) | + (flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO)); else open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); ret = drv->bdrv_open(bs, filename, open_flags); @@ -453,6 +453,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, /* if there is a backing file, use it */ BlockDriver *back_drv = NULL; bs->backing_hd = bdrv_new(""); + /* pass on read_only property to the backing_hd */ + bs->backing_hd->read_only = bs->read_only; path_combine(backing_filename, sizeof(backing_filename), filename, bs->backing_file); if (bs->backing_format[0] != '\0') @@ -731,6 +733,8 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset) return -ENOMEDIUM; if (!drv->bdrv_truncate) return -ENOTSUP; + if (bs->read_only) + return -EACCES; return drv->bdrv_truncate(bs, offset); } @@ -925,6 +929,13 @@ int bdrv_is_read_only(BlockDriverState *bs) return bs->read_only; } +int bdrv_set_read_only(BlockDriverState *bs, int read_only) +{ + int ret = bs->read_only; + bs->read_only = read_only; + return ret; +} + int bdrv_is_sg(BlockDriverState *bs) { return bs->sg; diff --git a/block.h b/block.h index a966afb..302010d 100644 --- a/block.h +++ b/block.h @@ -136,6 +136,7 @@ int bdrv_get_type_hint(BlockDriverState *bs); int bdrv_get_translation_hint(BlockDriverState *bs); int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); +int bdrv_set_read_only(BlockDriverState *bs, int read_only); int bdrv_is_sg(BlockDriverState *bs); int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); diff --git a/qemu-config.c b/qemu-config.c index cae92f7..4ac8fa0 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -71,6 +71,9 @@ QemuOptsList qemu_drive_opts = { .name = "addr", .type = QEMU_OPT_STRING, .help = "pci address (virtio only)", + },{ + .name = "readonly", + .type = QEMU_OPT_BOOL, }, { /* end if list */ } }, diff --git a/vl.c b/vl.c index eb2744e..97a940e 100644 --- a/vl.c +++ b/vl.c @@ -2007,6 +2007,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, int index; int cache; int aio = 0; + int ro = 0; int bdrv_flags, onerror; const char *devaddr; DriveInfo *dinfo; @@ -2038,6 +2039,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, secs = qemu_opt_get_number(opts, "secs", 0); snapshot = qemu_opt_get_bool(opts, "snapshot", 0); + ro = qemu_opt_get_bool(opts, "readonly", 0); file = qemu_opt_get(opts, "file"); serial = qemu_opt_get(opts, "serial"); @@ -2329,6 +2331,14 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, bdrv_flags &= ~BDRV_O_NATIVE_AIO; } + if (ro == 1) { + if (type == IF_IDE) { + fprintf(stderr, "qemu: readonly flag not supported for drive with ide interface\n"); + return NULL; + } + (void)bdrv_set_read_only(dinfo->bdrv, 1); + } + if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) { fprintf(stderr, "qemu: could not open disk image %s: %s\n", file, strerror(errno));